ROS相机内参标定详细步骤指南

本文涉及的产品
资源编排,不限时长
简介: 本文是关于ROS相机内参标定的详细步骤指南,包括了标定的目的、原理、所需材料、具体操作流程以及标定结果的分析。文章以Ubuntu20.04和ROS1 Noetic为测试环境,适用于单目RGB相机的内参标定,使用ros-noetic-camera-calibration工具包进行操作,并提供了标定过程中的注意事项和建议。

作者: Herman Ye @Galbot @Auromix
版本: V1.0
测试环境: Ubuntu20.04 、ROS1 Noetic
更新日期: 2023/09/14
注1: 本文内容中的硬件由 @Galbot 提供支持。
注2: @Auromix 是一个机器人爱好者开源组织。
注3: 由于笔者水平有限,以下内容可能存在错误。
注4: 本文中直接引用各包官方文档的图片等内容,版权归各官方所有。

为什么要标定?

相机标定的目的是为了确定相机内部参数和外部参数,以便修正图像并将图像坐标映射到世界坐标,或者从世界坐标映射到图像坐标。这个过程是计算机视觉和三维感知任务的关键步骤之一,它有以下主要目的:

  1. 减小畸变:相机镜头和传感器可能引入径向和切向畸变,使得图像中的直线变得弯曲或者物体的形状不准确。通过标定相机,可以矫正这些畸变,使图像更准确。
    在这里插入图片描述

  2. 确定内部参数(intrinsic parameters):内部参数包括焦距、主点坐标和相机畸变参数。这些参数是描述相机如何捕捉世界的重要因素,它们的准确值对于计算深度、距离和姿态等任务至关重要,相机内参标定就是为了获取精确的内部参数。

distortion_model: "plumb_bob"
D: [0.0, 0.0, 0.0, 0.0, 0.0]
K: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 1.0]
P: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 0.0, 1.0, 0.0]
  1. 确定外部参数:外部参数包括相机的位置和方向。这些参数描述了相机相对于世界坐标系的位置和朝向,允许将图像坐标映射到世界坐标,这对于机械臂的抓取很有帮助。
    该篇不涉及外参标定,将在机械臂手眼标定的文章中讲解相机的外参标定。
        <!-- xyz="-0.162861 0.177661 -0.626113" rpy="1.45853 -2.03383 1.49474" -->
        <node pkg="tf2_ros" type="static_transform_publisher" name="camera_link_broadcaster"
            args="-0.162861 0.177661 -0.626113   -0.173987 -0.703383 -0.14907 0.672873 Link6 left_arm_camera_link" />
  1. 相机姿态估计:相机标定还可用于估计相机在拍摄图像时的姿态,即相机的旋转和平移。这对于虚拟现实、增强现实、机器人导航和定位等应用至关重要。

标定的原理[选看]

使用OpenCV标定

通过OpenCV进行相机标定的原理可以参考OpenCV相机校准和三维重建文档
在这里插入图片描述

ros-noetic-camera-calibration

此处使用ros-noetic-camera-calibration工具包来方便地在ROS1 Noetic中标定相机。
camera_calibration包是一个允许使用棋盘格来轻松校准单目或立体相机的ROS包。

相机信息中的内参相关内容

以Intel Realsense彩色相机为例,以下是彩色相机的信息。

# rostopic echo /right_arm_camera/color/camera_info
---
header: 
  seq: 32308
  stamp: 
    secs: 1694683940
    nsecs: 530882359
  frame_id: "right_arm_camera_color_optical_frame"
height: 720
width: 1280
distortion_model: "plumb_bob"
D: [0.0, 0.0, 0.0, 0.0, 0.0]
K: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 1.0]
R: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
P: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 0.0, 1.0, 0.0]
binning_x: 0
binning_y: 0
roi: 
  x_offset: 0
  y_offset: 0
  height: 0
  width: 0
  do_rectify: False
---
header: 
  seq: 32309
  stamp: 
    secs: 1694683940
    nsecs: 564413071
  frame_id: "right_arm_camera_color_optical_frame"
height: 720
width: 1280
distortion_model: "plumb_bob"
D: [0.0, 0.0, 0.0, 0.0, 0.0]
K: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 1.0]
R: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
P: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 0.0, 1.0, 0.0]
binning_x: 0
binning_y: 0
roi: 
  x_offset: 0
  y_offset: 0
  height: 0
  width: 0
  do_rectify: False
---

其中包括相机的内部参数有关的参数:

当处理相机内参时,常见的三个参数是 DKP,此外相关的还有畸变模型。

  1. D畸变系数(distortion_coefficients):
    • D 是一个通常包含五个元素的数组 [k1, k2, p1, p2, k3],它用于描述相机图像中的径向和切向畸变。
    • k1k2 是径向畸变系数,它们用于描述镜头的弯曲形状,通常是负数。
    • p1p2 是切向畸变系数,它们用于描述镜头的畸变不对称性,通常是很小的值。
    • k3 是一个更高阶的径向畸变系数,通常情况下很小,有时甚至可以忽略。
    • D 用来表示径向和切向畸变。
D: [0.0, 0.0, 0.0, 0.0, 0.0]
  1. K相机内参矩阵(camera_matrix):
    • K 是一个3x3的矩阵,它包括了相机的内部参数,用于将相机坐标系中的三维点映射到图像平面上的二维坐标。
    • K 的主要元素包括:
      • K[0]K[4] 是焦距在图像 x 和 y 轴上的分量,通常以像素为单位。
      • K[2]K[5] 是光心在图像 x 和 y 轴上的坐标,也以像素为单位。
      • K[8] 通常是1,是一个归一化参数。
    • K 包含了焦距和主点的信息。
K: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 1.0]
  1. P投影矩阵(projection_matrix):
    • P 是一个3x4的矩阵,它包含了相机的投影参数,用于将相机坐标系中的三维点映射到图像坐标系。
    • P 的元素包括了内参和外参信息。
    • 其中 P[0]P[5] 分别对应于焦距 fxfy,用于将相机坐标系的 x 和 y 坐标映射到图像坐标系上。
    • P[2]P[6] 对应于光心的 x 和 y 坐标 cxcy
    • P[3]P[7] 通常为0,用于表示没有视角的旋转或平移。
    • P[10] 通常是1,是一个归一化参数。
    • 投影矩阵 P包含了相机的内部参数和畸变参数。
P: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 0.0, 1.0, 0.0]
  1. distortion_model"(畸变模型):
    distortion_model 是相机标定信息中的一个字段,用于描述相机的畸变模型。
    畸变模型是用来描述相机镜头产生的畸变效应的数学模型。
    在计算机视觉中,畸变通常分为径向畸变和切向畸变两种主要类型,而畸变模型用于对这些畸变进行建模和校正。
    Plumb Bob (钉形畸变模型):
  • “plumb_bob” 畸变模型是最常见的畸变模型之一,也是默认的畸变模型。它通常用于描述径向畸变(Radial Distortion)和切向畸变(Tangential Distortion)。
  • 径向畸变主要是由于镜头形状不完全圆形引起的,导致图像中心附近的像素与图像边缘的像素之间存在畸变。这种畸变通常用多项式函数建模。
  • 切向畸变则是由于相机镜头不完全平行于图像平面引起的,导致图像中心附近的像素存在畸变。切向畸变通常也用多项式函数建模。
  • “plumb_bob” 畸变模型使用径向和切向畸变系数(D)来描述这两种畸变。

标定的材料

  1. 棋盘格:需要准备一个大小适中的黑白棋盘格,计算大小8x6 方格大小9X7的棋盘格是常见的选择,但请注意,内部角点的数量比较少的情况下,标定可能会不够精确。

此处选用了计算大小11x8方格大小12x9的铝基板黑白棋盘格,边长为15mm作为示例,这些制作好的标定板有更高的标定精度。

方格大小计算大小是为了方便理解造的名词,将在之后解释。

在这里插入图片描述
如果手上没有标定板,也可以在线制作棋盘格并用A4纸打印出来,
推荐的参数如下:

Name Value
Target Type Checkerboard
Board Width 297
Board Height 210
Rows(方格大小) 7
Columns(方格大小) 9
Checker Width [mm] 25

在这里插入图片描述

注意事项:需要明确的是,棋盘格的计算大小是指内部角点的数量,按照OpenCV文档的描述,例如 计算大小 8x6 棋盘格实际上包含 9x7 个物理方格,也就是方格大小9X7

如图所示,数内部角点(图上红圈处)只有八个,也就是计算行大小为8,实际上的行方格数为9

在这里插入图片描述

在将棋盘格打印出来后,需要贴在平整的表面上。
在这里插入图片描述

  1. 良好的光照条件:确保拍摄相机标定图像的区域光线充足,并且没有遮挡物或其他棋盘格图案。

  2. 相机:需要标定的相机,已接入ROS1 Noetic,并且使用了rostopic获取相机发布的图像话题。

相机需要满足的需求:

同时,相机硬件需要提供适用于ROS的节点,以便能够发布必要的图像话题。

开始标定

单目RGB相机(monocular)

此处以right_arm_camera为例:

  • 1.下载ros-noetic-camera-calibration
sudo apt install ros-noetic-camera-calibration -y
  • 2.修改参数为需要校准的相机的参数
    需要获取的参数如下:
参数 参考值 解释
–size 8x6 棋盘格计算大小8行x6列
–square 0.025 棋盘格方格的边长大小0.025米(25mm)
image:= /right_arm_camera/color/image_raw 名为right_arm_camera的相机的彩色相机图像话题
camera:= /right_arm_camera 名为right_arm_camera相机

参数解释请参考camera_calibration文档

  • 3.运行校准程序
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.025 image:=/right_arm_camera/color/image_raw camera:=/right_arm_camera

注意:因为校准工具会查找相机节点的set_camera_info服务,如果无法正确启动,添加以下参数到命令中

 --no-service-check

下图为正常打开标定软件的图片:
在这里插入图片描述

  • 3.调整标定板
    按照以下顺序调整标定板,使得相机拍摄尽量多的不同视角下的有效照片:
  1. 前后移动标定板
  2. 上下移动标定板
  3. 左右移动标定板
  4. 沿Yaw轴旋转标定板
  5. 沿Pitch轴旋转标定板
  6. 沿Roll轴旋转标定板

在这里插入图片描述

当X、Y、Size、Skew结果都为绿色,非常良好时,点击CALIBRATE进行标定计算。
标定计算结束后点击SAVE保存标定结果。

保存的结果将被自动保存在/tmp目录下,名为calibrationdata.tar.gz

('Wrote calibration data to', '/tmp/calibrationdata.tar.gz')

通过以下命令将其解压到$HOME目录

# Create dir
mkdir ~/camera_calibration_result/
# Unzip
tar -xzvf /tmp/calibrationdata.tar.gz -C ~/camera_calibration_result/
# Go home
cd ~

在这里插入图片描述

标定结果

查看解压到$HOME目录下的标定结果ost.txt或者ost.yaml

# ost.txt
# oST version 5.0 parameters


[image]

width
1280

height
720

[narrow_stereo]

camera matrix
911.053619 0.000000 651.739848
0.000000 906.641596 351.747917
0.000000 0.000000 1.000000

distortion
0.102865 -0.173613 0.001142 0.005375 0.000000

rectification
1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000

projection
918.415080 0.000000 660.158706 0.000000
0.000000 923.612822 352.392856 0.000000
0.000000 0.000000 1.000000 0.000000
# ost.yaml
image_width: 1280
image_height: 720
camera_name: narrow_stereo
camera_matrix:
  rows: 3
  cols: 3
  data: [911.05362,   0.     , 651.73985,
           0.     , 906.6416 , 351.74792,
           0.     ,   0.     ,   1.     ]
distortion_model: plumb_bob
distortion_coefficients:
  rows: 1
  cols: 5
  data: [0.102865, -0.173613, 0.001142, 0.005375, 0.000000]
rectification_matrix:
  rows: 3
  cols: 3
  data: [1., 0., 0.,
         0., 1., 0.,
         0., 0., 1.]
projection_matrix:
  rows: 3
  cols: 4
  data: [918.41508,   0.     , 660.15871,   0.     ,
           0.     , 923.61282, 352.39286,   0.     ,
           0.     ,   0.     ,   1.     ,   0.     ]

和Intel 原厂标定的结果作对比,可以发现参数差不多:

D: [0.0, 0.0, 0.0, 0.0, 0.0]
K: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 1.0]
R: [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
P: [911.4010620117188, 0.0, 645.8338623046875, 0.0, 0.0, 910.145263671875, 347.9687194824219, 0.0, 0.0, 0.0, 1.0, 0.0]

后续

对于普通未经标定的相机,此时就可以用相机的手段进行内参数据的更新
对于Intel Realsense相机,参考MartyG所述,Realsense相机在出厂前已经标注过,因此通常不再需要再次标注内参。

因此,本文只是拿Realsense相机作为例子,这篇文章仍适用于其他需要人工标定的相机。

MartyG
3 years ago Edited
As well as the Dynamic Calibrator tool, you can also use an On-Chip Calibration tool that is built into the RealSense Viewer program to test the camera and provide a ‘heath check’ value for the calibration. There is a Tare tool in the Viewer too for improving depth measuring accuracy. Both tools can be found in a menu under the More option at the top of the Viewer’s options side-panel, and Intel have published a white-paper guide to use of On-Chip Calibration and Tare.
https://dev.intelrealsense.com/docs/self-calibration-for-depth-cameras
I would recommend using the Dynamic Calibrator when you need to perform a thorough and robust calibration of the camera’s imager components, and use On-Chip Calibration for more regular checks.
There is also the option of testing depth image quality and receiving feedback about it (such as the amount of error) using the Depth Quality Tool.
The normal version of the Dynamic Calibrator tool only calibrate extrinsics because it is extrinsics that have the most effect on depth quality. Users of the OEM version of the tool have the option of calibrating intrinsics too, though that system is aimed at engineering departments and manufacturing facilities, and 99% of RealSense users will not require it.

部分参考资料

https://wiki.ros.org/image\_pipeline/CameraInfo
http://wiki.ros.org/camera\_calibration
http://wiki.ros.org/camera\_calibration/Tutorials/StereoCalibration

相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
目录
相关文章
|
6月前
|
存储 Ubuntu 计算机视觉
使用ros标定相机的内参和外参
使用ros标定相机的内参和外参
266 2
|
数据采集 数据可视化 Ubuntu
相机和livox激光雷达外参标定:ROS功能包---livox_camera_lidar_calibration 使用方法
该功能包提供了一个手动校准Livox雷达和相机之间外参的方法,已经在Mid-40,Horizon和Tele-15上进行了验证。其中包含了计算相机内参,获得标定数据,优化计算外参和雷达相机融合应用相关的代码。本方案中使用了标定板角点作为标定目标物,由于Livox雷达非重复性扫描的特点,点云的密度较大,比较易于找到雷达点云中角点的准确位置。相机雷达的标定和融合也可以得到不错的结果。
相机和livox激光雷达外参标定:ROS功能包---livox_camera_lidar_calibration 使用方法
ROS——深度图转换伪面阵激光——depthimage_to_laserscan 功能包
ROS——深度图转换伪面阵激光——depthimage_to_laserscan 功能包
ROS——深度图转换伪面阵激光——depthimage_to_laserscan 功能包
|
机器学习/深度学习 Ubuntu 开发工具
相机和livox激光雷达外参标定:ROS功能包---livox_camera_lidar_calibration 介绍
**什么是相机与激光雷达外参标定?** 就是相机坐标系和激光雷达坐标系的TF变化。位置x,y,z 欧拉角 roll,pitch,yaw,6个变量构成一个4*4的旋转变换矩阵 标定的就是这个4维的旋转矩阵。 标定的方法有: - 基于特征 - 基于运动观测 - 基于最大化互信息 - 基于深度学习 基于特征 的方法是根据对应特征点求解PnP问题,需要标定板来获取特征 基于运动观测可以看作手眼标定问题,精度决定于相机和雷达的运动估计 基于最大化互信息认为图像灰度于反射强度具有相关性 基于深度学习需要长时间的训练并且泛化能力不高
相机和livox激光雷达外参标定:ROS功能包---livox_camera_lidar_calibration 介绍
|
数据可视化 计算机视觉
常用摄像头一些点云深度矫正ROS程序(ZED & kinect v2 & D415)(下)
常用摄像头一些点云深度矫正ROS程序(ZED & kinect v2 & D415)(下)
常用摄像头一些点云深度矫正ROS程序(ZED & kinect v2 & D415)(下)
|
XML 传感器 并行计算
常用摄像头一些点云深度矫正ROS程序(ZED & kinect v2 & D415)(上)
常用摄像头一些点云深度矫正ROS程序(ZED & kinect v2 & D415)(上)
常用摄像头一些点云深度矫正ROS程序(ZED & kinect v2 & D415)(上)
|
Ubuntu 机器人 定位技术
ros_gazebo/turtlebot3 室内仿真导航,提取camera/image和pose位姿真值,并将topic 时间同步对齐,最后制作成kitti 格式的数据集。
ros_gazebo/turtlebot3 室内仿真导航,提取camera/image和pose位姿真值,并将topic 时间同步对齐,最后制作成kitti 格式的数据集。
556 0
相机和livox激光雷达外参标定:在gazebo中搭建仿真场景
前两篇介绍了相机和livox激光雷达外参标定:ROS功能包的livox_camera_lidar_calibration 和使用方法. 具体链接: - [链接1](https://www.guyuehome.com/38522) - [链接2](https://www.guyuehome.com/38524) 本篇在gazebo中搭建可以模拟产生livox_camera_lidar_calibration功能包需要的数据的仿真场景.
相机和livox激光雷达外参标定:在gazebo中搭建仿真场景
|
XML 计算机视觉 数据格式
相机标定 matlab opencv ROS三种方法标定步骤(2)
二  ubuntu下Opencv的相机标定         一般直接用Opencv的源码就可以进行相机的标定,但是可能只是会实现结果,却不懂实现的过程,我也是模模糊糊的看了《计算机视觉中的多视图几何》以及实现一些经典的算法,对Opencv有一些了解才开始做相机的标定,可以先看看源码: #incl...
1494 0
|
计算机视觉
相机标定 matlab opencv ROS三种方法标定步骤(3)
三 ,  ROS 环境下 如何进行相机标定     刚开始做到的时候遇到一些问题没有记录下来,现在回头写的时候都是没有错误的结果了,首先使用ROS标定相机,   要知道如何查看节点之间的流程图  rosrun rqt_graph rqt_graph ,如何查看我们运行的节点  rosnode l...
1448 0

热门文章

最新文章

推荐镜像

更多