Incorrect matrix norm in geodesic_dist function
Closed this issue · 0 comments
In function geodesic_dist:
def geodesic_dist(R, R_gt): # _geo_err
R, R_gt = map(np.matrix, [R, R_gt])
# With out disp annoying error
_logRR, errest = logm(R.transpose()*R_gt, disp=False)
R_angle = norm(_logRR, 2) / sqrt(2)
return R_angle
The matrix 2-norm is incorrectly used, as the defenition of geodesic distance is in Frobenius norm.
This initial implementation geodesic_dist(R, R_gt) was simply trying to replicate the matlab evaluation code from RenderForCNN (ICCV 2015):
R_angle = norm(logm(R_pred'*R_label)) / sqrt(2);
However, we find it uses an incorrect matrix norm. Thanks @Davmo049 for discovering the issue.
The default mode of matrix norm function in matlab and python are different.
(In matlab, the default is 2 norm. In python, the default is Frobenius norm.)
So the above matlab code is indeed using default 2-norm of matrix, and thus so do my implementation in geodesic_dist(R, R_gt).
The later implementation geodesic_dist_new(R, R_gt) only borrows the idea from “3D Pose Regression using Convolutional Neural Networks” to accelerate computation, while ensures the same result is returned as geodesic_dist(R, R_gt).
The correct implementation would be:
def geodesic_dist(R, R_gt):
R, R_gt = map(np.matrix, [R, R_gt])
_logRR, errest = logm(R.transpose()*R_gt, disp=False)
R_angle = norm(_logRR, 'fro') / sqrt(2)
return R_angle
def geodesic_dist_new(R, R_gt):
R, R_gt = map(np.matrix, [R, R_gt])
# Do clipping to [-1,1].
# For a few cases, (tr(R)-1)/2 can be a little bit less/greater than -1/1.
logR_F = np.clip( (np.trace(R.transpose()*R_gt)-1.)/2., -1, 1)
R_angle = np.arccos( logR_F )
return R_angle