WHU-USI3DV/SGHR

Computation of the translation synchronization

qsisi opened this issue · 3 comments

qsisi commented

Thanks for the great work, I have a question for your implementation of translation synchronization.

In your implementation, the translation is computed using:

def leastsquare(locws, ts, pcrs, N):
'''
base : RiPi+ti = RjPj+tj
Pi = RijPj+tij
--> Ri(RijPj+tij)+ti = RjPj+tj
--> RiRij = Rj Ritij+ti = tj
--> -ti + tj = Ritij (3 formular)
least square:
B: (p*3)*(N*3)
P: (p*3)*(p*3)
L: Ritij--> (p*3)
'''
tpre = np.zeros([N,3])
p = locws.shape[0]
B = np.zeros([p*3, N*3])
P = np.eye(p*3)
L = np.zeros([p*3])
# get B and P
for pid in range(locws.shape[0]):
# the pid-th pair
i, j, w = int(locws[pid,0]), int(locws[pid,1]), locws[pid,2]
P[pid*3:(pid+1)*3] *= w
B[pid*3:(pid+1)*3, i*3:(i+1)*3] = -np.eye(3)
B[pid*3:(pid+1)*3, j*3:(j+1)*3] = np.eye(3)
# get L
for pid in range(locws.shape[0]):
# the pid-th pair
i, j, w = int(locws[pid,0]), int(locws[pid,1]), locws[pid,2]
L[pid*3:(pid+1)*3] = pcrs[i]@ts[pid] - (tpre[j]-tpre[i])
# delta
deltat = np.linalg.pinv(B.T@P@B)@(B.T@P@L)
tpre += deltat.reshape(N,3)
# final T
Tpre = []
for i in range(N):
r = pcrs[i]
t = tpre[i]
T = np.eye(4)
T[0:3,0:3] = r
T[0:3,-1] = t
Tpre.append(T[None,:,:])
Tpre = np.concatenate(Tpre, axis=0)
return Tpre

which corresponds to your paper:
image

But the original paper "Learning Transformation Synchronization" computes the translation following :
image

Because I failed to understand your implementation and the original implementation is more clearer, so following your code, I compute the translation using:

b = np.zeros([3*N])
for pid in range(len(locws)):
    i, j, w = int(locws[pid,0]), int(locws[pid,1]), locws[pid,2]
    xs, xe = i * 3, i * 3 + 3
    b[xs:xe] -= w * Rs[pid] @ (-Rs[pid].T@ts[pid])
tpre = np.linalg.pinv(L) @ b
tpre = tpre.reshape(N, 3)

However, the result tpre does not stay the same with your implementation.

So the two questions are:

Q1. What is the difference between these two implementations?

Q2. Why the results of these two implementations are not the same?

Thank you so much for your help.

Hi @qsisi ,
Sorry for the late reply and thanks for your interest!
In SGHR, the relative transformation aligns point cloud $P_j$ to point cloud $P_i$ , here $j>i$, i.e., $P_i = R_{ij} * P_j + t_{ij}$ s.t. $j>i$. (For consistence with FCGF/YOHO/SpinNet/GeoTrans.)
In LTS, the basic relative transformation is formulated as: $P_j = R_{ij} * P_i + t_{ij}$, s.t. $j>i$.
Thus, $R_{ij}^{LTS} = (R_{ij}^{SGHR})^T$ and $t_{ij}^{LTS} = -(R_{ij}^{SGHR})^T * t_{ij}^{SGHR}$.
Such a difference causes the differences of rotation and translation synchronization formulations. Specifically, for rotation synchronization, LTS uses $R_{ij}^T$ in its Eq.(1) while SGHR using $R_{ij}$ in Eq.(8).
For translation sychronization, I have not derived LTS‘s formulation carefully, but I believe it can be derived with the basic least square method or its variants: https://en.wikipedia.org/wiki/Least_squares, where the translation solution of SGHR comes from.

Yours,

qsisi commented

Thanks for your prompt reply, I did notice the "inverse" relations on rotations between LTS and SGHR, but I still could not derive the translation synchronization of your implementation. So may I ask did the code scripts come from other code bases?

Thank you so much for your help.

Hi @qsisi,
Sorry for the late reply!
This code snippet is original and is implemented based on Linear Least Square Algorithm and the following formulas:

'''
base : RiPi+ti = RjPj+tj
Pi = RijPj+tij
--> Ri(RijPj+tij)+ti = RjPj+tj
--> RiRij = Rj Ritij+ti = tj
--> -ti + tj = Ritij (3 formular)
least square:
B: (p*3)*(N*3)
P: (p*3)*(p*3)
L: Ritij--> (p*3)
'''

yours,