计算通过姿态估计找到的棋盘的正规方程

Calculate the normal equation for a checkerboard found through pose estimation

我正在从事激光扫描项目。为此,我正在关注此 paper 以进行校准。我目前被卡住了,作者计算了用于校准相机的棋盘平面参数(以及接下来的激光平面)。

为了生成测试数据,我使用了Blender,根据raspberry pi V2. 提供相机数据(焦距、像素大小等) 在 calculating/finding intrinsic camera matrix 与 OpenCv (Python 3)

之后
cv.findChessboardCorners()

cv.cornerSubPix()

在 opencv.org 的 tutorial 之后,我正在使用

cv.solvePnP()

获取平面的旋转和平移矢量的函数。使用以下代码,我现在正在按照作者的公式计算距相机中心的法线距离和符号距离:

normalvector = rotationmatrix * [[0][0][1]]
distance = (normalvector * -1)T * translational vector

(T = 转置向量)

import numpy as np
import cv2 as cv

with np.load("vectorsRT.npz", "r") as file:
    rvecs, tvecs = [file[i] for i in ("rotationVectors", "translationVectors")]

rot_matrix = cv.Rodrigues(rvecs)[0]
mult_matrix = np.array([[0],[0],[1]])

normal_vector = np.matmul(rot_matrix, mult_matrix)
normal_vector_neg = normal_vector * -1
normal_vector_neg_transposed = np.transpose(normal_vector_neg)

signed_distance = np.matmul(normal_vector_neg_transposed, tvecs)

print("normal_vector:", normal_vector)    
print("signed_distance:", signed_distance)

有了这个,我现在得到了一个法向量和到相机中心的距离,例如: normal_vector:

[[-0.0604253 ]
 [ 0.16923283]
 [ 0.98372203]]

signed_distance:

[[[-51.67514398]]]

从搅拌机我得到以下正常

[[-0.00117647]
 [-0.00333335]
 [-0.01939508]]

法线或多或少是等效的,但是,现在如何将带符号的距离转换为世界坐标系中平面的支持向量,从而得到完整的平面方程?

我想我找到了答案:在这个 post 之后,我引入了符号距离的比例因子 s,以将距离转换为真实世界的距离(以毫米为单位)。

calc_distance_camera_plane = signed_distance * s 

这个比例因子是用一个已知的平面距离除以的(例如:棋盘在世界坐标系Z=0,相机固定在一个位置,例如:Z=25mm,向下看)通过那个确切图像的signed_distance

scale_factor = dist_camera_world_orign / signed_distance

利用该比例因子,可以将每个 signed_distance 转换为真实世界距离 (camera-plane) 并获得真实世界距离 (world orign-plane)

 dist_world_orign_plane = dist_camera_world_orign - calc_distance_camera_plane

然后我寻找的平面方程由计算出的法线和一个带有

的点给出
(0, 0, dist_world_orign_plane)

因为我有原始平面的精确值(图像是用搅拌机计算的),我可以将 camera_plane 的计算距离与实际距离(实际 distance/calculated 距离)进行比较:

n = 10
mean difference: 1.005
standard deviation: 0.0281

我认为这是进一步测试的良好起点。 希望这个回答也能帮到别人,干杯