开放计算机视觉库(OPENCV):Calibratecamera2的重投影误差和自定义计算的误差不一致。

8

我有一个Python脚本,使用calibrateCamera2方法从几个棋盘的视图来校准相机。成功校准后,我会对所有原始点进行绘图,并重新计算再投影误差。令我惊讶的是,OpenCV计算出的再投影误差和我的稍有不同。我认为这很奇怪。难道我计算的方法有误吗?

obj_points = []# 3d point in real world space. List of arrays
img_points = []# 2d points in image plane. List of arrays

...

ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, (w, h), camera_matrix, dist_coeffs, rvecs, tvecs, calib_flags +cv2.CALIB_USE_INTRINSIC_GUESS, criteria)
print "Final reprojection error opencv: ", ret   #Compute mean of reprojection error
tot_mean_error=0
mean_error_image = 0
for i in xrange(len(obj_points)):
    reprojected_points, _ = cv2.projectPoints(obj_points[i], rvecs[i], tvecs[i], camera_matrix, dist_coeffs)
    reprojected_points=reprojected_points.reshape(-1,2)
    mean_error_image=np.sum(np.sum(np.abs(img_points[i]-reprojected_points)**2,axis=-1)**(1./2))/np.alen(reprojected_points)
    tot_mean_error +=mean_error_image

mean_error=tot_mean_error/len(obj_points)
print "Mean reprojection error: ", mean_error

OpenCV最终重投影误差: 0.571030279037

平均重投影误差: 0.438696960449

1个回答

8

我之前计算的方式是错误的/不同。我使用了这种公式:

formula

但是OpenCV使用了这个公式:

fomrula_opencv

所以,如果有人感兴趣,代码现在看起来像这样:

#Compute mean of reprojection error
tot_error=0
total_points=0
for i in xrange(len(obj_points)):
    reprojected_points, _ = cv2.projectPoints(obj_points[i], rvecs[i], tvecs[i], camera_matrix, dist_coeffs)
    reprojected_points=reprojected_points.reshape(-1,2)
    tot_error+=np.sum(np.abs(img_points[i]-reprojected_points)**2)
    total_points+=len(obj_points[i])

mean_error=np.sqrt(tot_error/total_points)
print "Mean reprojection error: ", mean_error

OpenCV 最终投影误差为:0.571030279037

平均投影误差为:0.571030718956


4
你的代码是正确的,但是那个公式与代码不匹配。你的代码计算单个图像的重新投影误差,分子中应该只有一个 d(x, x')。分子中包含两个位移误差之和的方程式是用于最小化同一视角下两张图片对应点的重投影误差的单应性矩阵所使用的。 - rob3c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接