多传感器标定——相机内参标定

一、前言

之前写过一篇文章(相机内参、外参、畸变系数简介),感觉应该把这几个东西说的还算明白,但是里边并没有深究该如何进行标定,正好在这次学习中进行补充。
我面试时的体验就是,如果你没有那种一眼吊的科研成果,那么项目中再大的创新也就那么样,不如把时间花在了解项目细节上,比如内参标定到底是怎么实现的,而不是面试官问起你这个问题,你只能跟我一样傻笑道我调了opencv的库。。。。。。接着面试官又问,函数的每个输入输出都是什么?对不起,沉默是今晚的康桥。。。。。。哥们都是现用现百度。

二、内参标定流程

  1. 标定板准备
    标定板种类有很多种,棋盘格、圆点阵、ChArUco板。为了避免歧义性——指定的3D角点坐标与算法输出的角点像素坐标存在多种对应关系,棋盘格和圆点阵的关键点阵列尺寸都是奇数×偶数,并且圆点阵是非对称排列的,以保证匹配的唯一性。ChArUco板长很像是一堆二维码,不像前两种板需要所有关键点都出现在视野中,ChArUco板允许出现遮挡。

    我只用过前两种,实际用下来感觉精度没有很大差别?但是由于我的应用场景是机器人的手眼标定,所以更喜欢使用棋盘格,因为棋盘格更容易验证标定精度。至于到底哪个更好,好像也没个确切结论,大多数人可能是因为opencv里说非对称圆点阵更好就认为它更好,但是一篇论文中说可能棋盘格会是更好的选择?观点来源

    至于标定板的制作,需要考虑到你的精度要求。你当然可以自己打印贴在板子上,但据我自己经验,打印出来的尺寸总跟我设计的尺寸有点差别,不清楚是不是打印设置的原因,还得用尺子去量,并且贴在板子上也不会完全平整,这都引入了误差,只适合于用在一些低精度要求的场景下。也可以直接淘宝解君愁,你会猛的发现,高精度的标定板居然可以那么贵。。。。。

  2. 拍摄标定图像
    在不同位置或角度下,使用相机拍摄多张包含标定板的图像,尽量覆盖整个图像传感器的视场。我之前搞机器人手眼标定是拿了一块标定板,不断变换机器人位姿去采集图像,为了获得更好的效果,两次采集之间的位姿还有要求,采数据搞得我很痛苦,但现在发现是贫穷限制了我的想象,完全可以固定机器人,在视场中摆放各种标定板。

  3. 对采集到的图像做特征点提取,获得像素坐标

  4. 对焦距、主点和镜头畸变进行估计

  5. 计算重投影误差
    这边记录一个问题,计算重投影误差只能评估标定好坏?还是说可以做类似反向传播的过程,进一步优化内参参数。(最开始授课老师说可以,但是后边提到的只是其评估作用,比较疑惑)

比较常用的标定方法是张正友标定法,理论推导可以参考这篇链接,写的很详细参考文章

下面仅作为我自己的简单记录,没啥必要看
1. 将图像视作无畸变计算内外参(先算H,再算B,再算A,再求G)
2. 用内外参将3D坐标(认为指定的)变换成像素坐标,视作无畸变坐标
3. 采集图像中提取出的角点是有畸变坐标,无畸变为输入,有畸变为输出,求解畸变系数
4. 循环几次,直至误差满足要求
注:求解的最低要求是,每张图片上至少4个角点以满足对H的求取(齐次矩阵,8个自由度,每个角点uv提供两个方程)。至少3张标定板图片完成对B的求取(B是 A − T A − 1 A^{-T}A^{-1} ATA1,3*3对称,所以有6个自由度)。

三、如何提升标定精度

  • 提高数据质量:一方面提高标定板制作精度,另一方面采集的数据也要尽量高质量(不同角度、不同距离的数据都要有;要尽量覆盖全部视野;采集到的数据要完整清晰)
  • 选取更高精度的模型:张正友标定模型中只考虑了两项畸变系数,并且也不适用于FOV特别大的鱼眼镜头,当FOV超过170°时可以选用OCamCalib模型
  • 标定存在随机性,可以多次标定取平均值

四、精度验证

  • 观察图像是否正常
  • 计算重投影误差:但重投影误差只能评估标定结果在当前数据集上的表现
  • 直线度检测(这地方没看明白怎么做的)

五、内外参联合标定

这部分完全听不懂在干什么,课上说这个方法出自mobileye,得查一下
在这里插入图片描述

课件里这部分说的是相机和雷达之间的外参,与自车之间的目前还不知道如何标定
在这里插入图片描述
最终目标是希望相机视野中各个区域的像素都能和雷达精确的配准
在这里插入图片描述
下面的图展示了,分开标定和联合标定的差异,a是分开标定的原图,b是分开标定的结果图,cd是联合标定的图。
尽管b中畸变去除的已经比较好了,但可能是内参标定时候其他系数有误差,导致相机与雷达对不齐。而联合标定会对参数做迭代优化,使得最终结果尽可能对齐。本质上就是开环和闭环的区别喽~
在这里插入图片描述

  • 25
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
相机内参标定是通过对相机进行一系列的参数估计,以便能够准确地将图像坐标转换为真实世界中的物体坐标。在Python中,可以使用OpenCV库来进行相机内参标定。 以下是一个基本的相机内参标定的Python代码示例: ```python import numpy as np import cv2 # 定义棋盘格尺寸 pattern_size = (8, 6) # 准备用于保存棋盘角点的列表 obj_points = [] # 保存物体点的3D坐标 img_points = [] # 保存图像点的2D坐标 # 生成物体点的坐标 objp = np.zeros((np.prod(pattern_size), 3), np.float32) objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2) # 读取图像 images = [...] # 填入需要标定的图像路径列表 for img_path in images: img = cv2.imread(img_path) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 查找棋盘角点 ret, corners = cv2.findChessboardCorners(gray, pattern_size, None) if ret: obj_points.append(objp) img_points.append(corners) # 在图像上绘制角点并显示 cv2.drawChessboardCorners(img, pattern_size, corners, ret) cv2.imshow('Chessboard Corners', img) cv2.waitKey(500) # 显示图片500毫秒 cv2.destroyAllWindows() # 进行相机内参标定 ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, gray.shape[::-1], None, None) # 打印相机内参矩阵和畸变系数 print("相机内参矩阵:") print(mtx) print("\n畸变系数:") print(dist) ``` 上述代码中,首先定义了棋盘格的尺寸,然后准备用于保存棋盘角点的列表。接下来,生成物体点的3D坐标,并读取需要标定的图像。使用`cv2.findChessboardCorners()`函数查找图像中的棋盘角点,并将找到的角点保存到`img_points`列表中。然后在图像上绘制角点并显示。 最后,使用`cv2.calibrateCamera()`函数进行相机内参标定,返回相机内参矩阵和畸变系数。打印出这些参数即可完成相机内参标定。 请注意,上述代码仅提供了一个基本的相机内参标定示例,实际应用中可能需要更多的处理和参数调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糊烟乱雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值