0、引言
在图像测量过程以及机器视觉应用中,为确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,必须建立相机成像的几何模型,这些几何模型参数就是相机参数。在大多数条件下这些参数必须通过实验与计算才能得到,这个求解参数(内参、外参、畸变参数)的过程就称之为相机标定(或摄像机标定)。无论是在图像测量或者机器视觉应用中,相机参数的标定都是非常关键的环节,其标定结果的精度及算法的稳定性直接影响相机工作产生结果的准确性。因此,做好相机标定是做好后续工作的前提,提高标定精度是科研工作的重点所在。
畸变(distortion)是对直线投影(rectilinear projection)的一种偏移。简单来说直线投影是场景内的一条直线投影到图片上也保持为一条直线。畸变简单来说就是一条直线投影到图片上不能保持为一条直线了,这是一种光学畸变(optical aberration),可能由于摄像机镜头的原因。

0.1 一图说明为什么要标定相机
在这里插入图片描述

在这里插入图片描述

标定相机要求得就是相机的内参和上面提到的外参R、T矩阵为相机的外参矩阵。这个关于内外参数的博客我建议大家看一看的。

0.2 关于标定过程中是自动标定板还是移动相机
因为在采集过程中,需要对标定板进行多个角度的拍摄,甚至有要求是不同高度位置的拍摄。因此,这个时候就要求要移动标定板或者相机。
有一个百度的无良玩家真的是把我坑了,他竟然让人移动相机。说实话,如果移动相机,那标定还有什么意义?
更何况,如果我没有记错的话,相机移动一次就要重新标定一次,那你移动相机跟干嘛?

所以,我的建议是大家移动标定板,旋转不同角度。

0.3 采集过程光照和标定板的放置
首先,在采集图像的时候,一定要保证光线的充足。
其次,在移动的过程中,一定要保证标定板是水平的。不能一定,也一定要尽量保证。

1、宏观的标定步骤
1、打印一张棋盘格,把它贴在一个平面上,作为标定物。
2、通过调整标定板或摄像机的方向(我是强烈建议不要移动摄像机),为标定物拍摄一些不同方向的照片。
3、从照片中提取棋盘格角点。
4、估算理想无畸变的情况下,五个内参和六个外参。
5、应用最小二乘法(或者其他什么算法)估算实际存在径向畸变下的畸变系数。
6、极大似然法,优化估计,提升估计精度

2、基于ROS自带的camera-clibration的USB相机的标定
事实上,标定的速度取决于相机的质量和标定板的质量,由于我现在用的是很low的一个相机,所以在采集图像的时候都很麻烦,每次得十来分钟。
我有一个kinectV2相机,但是目前还没打算用。因为我在等我的KUKA七轴。
首先打印标定板
在这里插入图片描述

这个板子其实不需要去网上买,自己去打印社制作一个就行了,15块钱左右,不是一张纸,是一块板子。
打印的时候不要放缩,按照实际尺寸打印,然后制作板子。

安装camera-clibration标定包

sudo apt-get install ros-melodic-camera-calibration

我用的是ubuntu18.04版本,这边melodic是ubuntu18.04对应的ROS的版本。根据你ROS版本修改。

启动摄像头

roslaunch detection_color usb_cam.launch

这边我把摄像头启动写成了一个launch文件,放在了detection_color 这个功能包下面。
launch文件如下:

<launch>
 
  <node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" >
    <param name="video_device" value="/dev/video0" />
    <param name="image_width" value="640" />
    <param name="image_height" value="480" />
    <param name="pixel_format" value="yuyv" />
    <param name="camera_frame_id" value="usb_cam" />
    <param name="io_method" value="mmap"/>
  
    <param name="camera_info_url" type="string" value="file://$(find detection_color)/camera_calibration.yaml"/>
  </node>
</launch>

在这里插入图片描述

启动摄像头之后,调整你的摄像头位置,保证摄像头的视野。

这个时候会警告,没有标定文件

在这里插入图片描述

启动标定程序

rosrun camera_calibration cameracalibrator.py --size 11x9 --square 0.02 image:=/usb_cam/image_raw camera:=/usb_cam

这里面 size 11x9是标定板中格子内点的数量,就是四个格子的交点的数量,11和9之间的那个是x(xyz的x)。square 0.02是格子的边长,没每个格子2cm,这里的单位是米,所以是0.02。

在这里插入图片描述

启动之后的效果如下:

在这里插入图片描述

这个时候,右边的四个选项是灰色的,等我们采集足够的图像之后,第一个就会变成蓝色,然后点击。

在这里插入图片描述

出现这种颜色的线,表示开始标定并采数据。
点击后计算机开始计算,这时候计算机会卡,不要担心,等一会就行了。

在这里插入图片描述

当右侧第一个不是灰色的时候,点击它。计算机开始计算转换矩阵。

然后出现下面的结果

在这里插入图片描述

三个全部变成蓝色。
这时点击save。终端会出现下面的结果。根据地址提示,找到我们的标定结果,把它解压出来

在这里插入图片描述

这个时候我们就可以把这个标定界面关闭了。

到计算机主页面,打开文件夹
点击Other Locatons
点击Computer

在这里插入图片描述

在点击tmp

在这里插入图片描述

解压这个calibration,就能看到我们采集的图像 和标定对的结果

在这里插入图片描述

大家能看到那个ost.yaml文件。把这个文件夹复制下来,放到你启动摄像头的launch文件所在的包里面。
改名为camera_calibration.yaml

在这里插入图片描述

这时,我们需要修改启动摄像头的launch文件。
具体修改方法就是在最下面添加一行代码

<launch>
 
  <node name="usb_cam" pkg="usb_cam" type="usb_cam_node" output="screen" >
    <param name="video_device" value="/dev/video0" />
    <param name="image_width" value="640" />
    <param name="image_height" value="480" />
    <param name="pixel_format" value="yuyv" />
    <param name="camera_frame_id" value="usb_cam" />
    <param name="io_method" value="mmap"/>
  
  <!--Since I don't input Chinese characters here, I speak it in English. The following paragraph is added-->
    <param name="camera_info_url" type="string" value="file://$(find detection_color)/camera_calibration.yaml"/>
  </node>
</launch>

这个时候,我们在启动摄像头的时候,就没有上面的那个警告了
但是新的警告不匹配又出现了

在这里插入图片描述

这个问题是node中came的名字和yaml中的名字不一致造成的,
然后找到yaml文件,把narrow_stereo改为head_camera,两者保持一直就ok
原始的camera_calibration.yaml如下

在这里插入图片描述

修改后的如下,没修改的我就不截图了

在这里插入图片描述

这个时候,在启动相机还剩一个警告。
这个警告是这样说的
警告][1624277866.393154464]:相机校准文件未指定畸变模型,假设垂直摆动
不在乎

在这里插入图片描述

至此呢。相机内参标定就搞好了,下一步就是标定相机和机械臂之间的外参了。

注意

标定好的相机就不要移动它了,一定不要移动!!!!!!