一种利用棋盘格进行激光雷达与相机标定方法

1基本原理

1.1相机模型

相机图像坐标系与世界坐标系之间的关系可以表示为:
p ∼ K ( R P + t ) (1) \mathrm{p} \sim \mathrm{K}(R P+\mathrm{t})\tag{1} pK(RP+t)(1)
其中 p \mathrm{p} p为图像坐标系坐标, P {P} P为世界坐标系坐标, R R R表示为相机坐标系与世界坐标系之间的旋转矩阵, t \mathrm{t} t表示为相机光心在世界坐标系在坐标, K \mathrm{K} K表示内参矩阵。
在这里忽略镜头畸变影响,或者已经对镜头畸变进行了处理。

1.2相机与激光雷达之间的关系

设相机坐标系下点 P P P在激光雷达坐标系对应的点为 P f P^f Pf,则二者有如下关系:
P f = Φ P + Δ (2) P^f=\Phi P+\Delta\tag{2} Pf=ΦP+Δ(2)
其中, Φ \Phi Φ Δ \Delta Δ分别为相机坐标系与雷达坐标系之间的旋转与平移量。相机与雷达标定的目的即是要求解出 Φ \Phi Φ Δ \Delta Δ

1.3几何约束

本文提供的标定方法是在系统前面放置一个平面图案,比如棋盘格,相机和激光测距仪都可以测量到。同时使用相机和激光雷达对平面测量。定义标定平面为棋盘格表面的平面。
在不失一般性的情况下,我们假设标定平面在世界坐标系中其 Z = 0 Z=0 Z=0。在相机坐标系中,标定平面可以由3维向量 N N N参数化表示, N N N平行于标定平面的法线,其模长 ∥ N ∥ \|N\| N等于相机到标定平面的距离。由公式(1)我们可以得出:
N = − R ( R ⊤ ⋅ t ) (3) N=-R\left(R^{\top} \cdot \mathrm{t}\right)\tag{3} N=R(Rt)(3)
由于激光雷达点位于标定平面上,可以得到一个几何约束。由公式(2)可以得到:

P = Φ − 1 ( P f − Δ ) P=\Phi^{-1}\left(P^f-\Delta\right) P=Φ1(PfΔ)。由于位于标定板的相机坐标系下坐标 P P P由向量 N N N定义,它满足 N ⋅ P = ∥ N ∥ 2 N \cdot P=\|N\|^2 NP=N2。然后可以得到:
N ⋅ Φ − 1 ( P f − Δ ) = ∥ N ∥ 2 (4) N \cdot \Phi^{-1}\left(P^f-\Delta\right)=\|N\|^2\tag{4} NΦ1(PfΔ)=N2(4)
给定一个雷达点 P f P^f Pf和向量 N N N,即可求解 Φ \Phi Φ, Δ \Delta Δ

2求解方法

1.1线性方法

假设所有激光点的Y值为0(这里是针对二维激光雷达而言),激光雷达点 P f = [ X , Z , 1 ] P^f=[X,Z,1] Pf=[X,Z,1]。公式(4)可以变为:
N ⋅ H P ^ f = ∥ N ∥ 2 (5) N \cdot H \hat{P}^f=\|N\|^2\tag{5} NHP^f=N2(5)
H = Φ − 1 ( 1 0 0 0 − Δ 0 1 ) H=\Phi^{-1}\left(\begin{array}{lll}1 & 0 \\ 0 & 0 & -\Delta \\ 0 & 1\end{array}\right) H=Φ1 100001Δ ,表示雷达坐标系和相机坐标系之间的关系。对于标定平面的每个旋转和平移而言,可以得到很多关于 H H H的线性方程,使用最小二乘可以求解矩阵 H H H元素。得到 H H H之后,可以得到标定参数:
Φ = [ H 1 , − H 1 × H 2 , H 2 ] ⊤ Δ = − [ H 1 , − H 1 × H 2 , H 2 ] ⊤ H 3 \begin{aligned} \Phi & =\left[H_{1},-H_{1} \times H_{2}, H_{2}\right]^{\top} \\ \Delta & =-\left[H_{1},-H_{1} \times H_{2}, H_{2}\right]^{\top} H_{3} \end{aligned} ΦΔ=[H1,H1×H2,H2]=[H1,H1×H2,H2]H3
H i H_i Hi表示 H H H的列向量。但是这种方法得到的旋转矩阵,不满足正交性,精度不高。可以采用第二种非线性方法求解。

1.2非线性方法

对于不同的标定板的pose(R,t)。定义误差函数:
∑ i ∑ j ( N i ∥ N i ∥ ⋅ ( Φ − 1 ( P i j f − Δ ) ) − ∥ N i ∥ ) 2 (6) \sum_{i} \sum_{j}\left(\frac{N_{i}}{\left\|N_{i}\right\|} \cdot\left(\Phi^{-1}\left(P_{i j}^{f}-\Delta\right)\right)-\left\|N_{i}\right\|\right)^{2}\tag{6} ij(NiNi(Φ1(PijfΔ))Ni)2(6)
N i N_i Ni为标定板在第 i i i个pose对应的平面参数。 P i j f P_{i j}^{f} Pijf为第 i i i个pose对应的第 j j j个激光雷达点坐标。使用线性方法获取标定参数初值,然后利用非线性最小二乘,最小化误差函数,即可求解标定参数。
参考文献:
《Extrinsic calibration of a camera and laser range finder (improves camera calibration》
1

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
相机标定是指确定相机的内部参数(如焦距、主点位置等)和外部参数(如旋转矩阵、平移向量等),以便在三维空间中精确地测量物体的位置和大小。利用棋盘进行相机标定一种常用的方法。 下面是Python中使用OpenCV库进行棋盘标定的步骤: 1. 采集棋盘图像 首先在棋盘上贴上黑白相间的方块,然后使用相机拍摄这个棋盘的多个角度的图像。注意拍摄时棋盘应该保持平整,光线应该充足并且均匀。 2. 检测棋盘角点 使用OpenCV中的cv2.findChessboardCorners()函数来检测棋盘角点。该函数会返回一个布尔值和一个角点数组。如果找到了角点,则布尔值为True,否则为False。角点数组包含了所有检测到的角点的坐标。 3. 标定相机 将检测到的角点坐标传递给cv2.calibrateCamera()函数进行相机标定。该函数会返回相机的内部参数(如相机矩阵、畸变系数等)和外部参数(如旋转矩阵、平移向量等)。 4. 优化标定结果 使用cv2.undistort()函数将图像进行校正,以获得更好的结果。 下面是完整的Python代码示例: ```python import numpy as np import cv2 # 定义棋盘大小 chessboard_size = (9, 6) # 准备棋盘图像 objp = np.zeros((np.prod(chessboard_size), 3), np.float32) objp[:, :2] = np.mgrid[0:chessboard_size[0], 0:chessboard_size[1]].T.reshape(-1, 2) obj_points = [] img_points = [] # 读取棋盘图像 images = glob.glob('calibration_images/*.jpg') # 遍历所有图像 for fname in images: img = cv2.imread(fname) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 检测棋盘角点 ret, corners = cv2.findChessboardCorners(gray, chessboard_size, None) # 如果找到了角点 if ret == True: obj_points.append(objp) img_points.append(corners) # 在图像中绘制角点 cv2.drawChessboardCorners(img, chessboard_size, corners, ret) # 显示当前图像 cv2.imshow('img', img) cv2.waitKey(500) # 标定相机 ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, gray.shape[::-1], None, None) # 优化标定结果 img = cv2.imread('calibration_images/1.jpg') h, w = img.shape[:2] new_mtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h)) # 显示校正后的图像 dst = cv2.undistort(img, mtx, dist, None, new_mtx) cv2.imshow('dst', dst) cv2.waitKey(0) # 保存标定结果 np.savez('calibration.npz', ret=ret, mtx=mtx, dist=dist, rvecs=rvecs, tvecs=tvecs) ``` 该代码将棋盘图像存放在calibration_images文件夹中。在运行脚本之后,程序会依次显示每个棋盘图像,并在图像中绘制出检测到的角点。最后,程序会将标定结果保存在calibration.npz文件中,并显示校正后的第一张图像。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值