产品服务 技术交流 激光雷达 机器视觉 ROS教程 最新公告 讨论区 杂谈 行业动态

如何标定单目摄像头


  • administrators

    在本文中我们会使用camera_calibration 的 cameracalibrator.py节点来标定单目摄像头。

    1.开始之前

    确保你满足以下几个条件

    1. 一个很大的尺寸已知的标定板。在这篇教程中我们采用8x6的边长为108mm的标定板。
      标定过程中会使用方格的定点,所以一个8x6的板子实际上是9个方格宽和7个方格高。就和下面的例子一样。
    2. 一个空旷的5mx5m的环境。而且不能有类似的标定板。
    3. 一个能够通过ROS发布图像数据的摄像头

    2. 编译

    首先下载软件依赖,编译软件

    rosdep install camera_calibration
    

    确认你的摄像头正在通过ROS发布图像数据。通过查看topic来确认图像消息已经被发布。

    rostopic list
    

    这样会显示出所有已经发布的topic,看看里面是不是有image_raw的topic。大多数的ROS摄像头驱动所发布的消息是

    /camera_node/camera_info
    /camera_node/image_raw
    

    如果你有多个摄像头或者驱动程序有自己的命名空间,那么你的topic可能会与此有些不同。

    3. 运行标定节点

    你需要载入需要标定的图像话题来开始标定

    rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.108 image:=/camera_node/image_raw camera:=/camera_node
    

    这样会打开一个标定窗口。其中我们的棋盘格会被高亮显示。

    0_1528544940077_3d09c570-2c68-4595-bb64-a50c85d33cb7-image.png

    如果没有成功打开窗口程序,可以尝试增加下面的参数

    --no-service-check
    

    如果你没有发现任何彩色的点,那么你要确认你数的是顶点个数而不是方块的个数。

    3.1 双棋盘格

    从Diamondback版本开始,你可以使用多个尺寸的棋盘格来标定摄像头。如果想要使用多个棋盘格,你需要指定多个--size --square选项。确保棋盘格有不同的尺寸,这样标定程序才能够把它们区分出来。

    4. 移动棋盘格

    为了能够得到较好的标定结果,你需要在摄像头前来回移动棋盘格。保证以下几点

    1. 棋盘格在摄像头视野范围的上下左右四个角
      X条表示视野的左右范围
      Y条表示视野的上下范围
      size条表示在摄像头前后和倾斜
    2. 棋盘格占满整个视野
    3. 棋盘格在上下左右倾斜

    在每一步中都要保持不动直到图片显示高亮颜色。

    0_1528545549959_ebf66791-1e96-4908-b2ef-c4d955a80619-image.png

    0_1528545556918_e3e74a88-90e5-40c3-bd0c-7479386b3871-image.png

    0_1528545568609_683bd8ea-227c-47e9-ac26-684003bf2012-image.png

    0_1528545574671_ccd00365-18ee-4057-b152-0fad951874ed-image.png

    0_1528545606361_c68a944a-def0-42a4-8123-b84c2c9b0a4a-image.png

    0_1528545612970_5a017696-fd10-4dba-8099-8da2f57c8678-image.png

    在你移动标定板的过程中你会看到三个条的长度在不断的增加。当标定按钮亮起的时候,你就已经有足够的数据开始标定了。点击标定按钮开始标定。
    标定过程会需要几分钟。窗口可能会失去响应,但是一定要继续等,程序在正常运行中。

    0_1528545767981_22ec4821-b88e-4358-b891-7e41b4b1b201-image.png

    1. 标定结果
      当标定完成之后,你会在终端中看到标定结果。同时窗口也会显示标定后的图像。

    0_1528545849309_a51c40fa-5397-41ce-af6b-5f756524e8ec-image.png

    一个成功的标定结果会使现实情况中直的东西在图像中仍然显示是直的。

    失败的标定通常会没有图像显示,或者不能够保证直线。

    成功标定之后你可以使用上面的滑条来调整显示区域方块的尺寸。尺度0代表图像中的所有区域的像素点都是有效的。标定区域是没有边界的,但是原始图像的一些像素点会被丢弃。尺度1代表所有的原始图像的像素点都是可见的,但是标定区域却没有点。

    D =  [-0.33758562758914146, 0.11161239414304096, -0.00021819272592442094, -3.029195446330518e-05]
    K =  [430.21554970319971, 0.0, 306.6913434743704, 0.0, 430.53169252696676, 227.22480030078816, 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 =  [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0]
    # oST version 5.0 parameters
    
    
    [image]
    
    width
    640
    
    height
    480
    
    [narrow_stereo/left]
    
    camera matrix
    430.215550 0.000000 306.691343
    0.000000 430.531693 227.224800
    0.000000 0.000000 1.000000
    
    distortion
    -0.337586 0.111612 -0.000218 -0.000030 0.0000
    
    rectification
    1.000000 0.000000 0.000000
    0.000000 1.000000 0.000000
    0.000000 0.000000 1.000000
    
    projection
    1.000000 0.000000 0.000000 0.000000
    0.000000 1.000000 0.000000 0.000000
    0.000000 0.000000 1.000000 0.000000
    

    如果你对标定结果比较满意,可以点击提交按钮将参数发送给摄像头存储起来。图形程序会自动退出,终端上会显示保存标定数据。

    6. 保存参数至usb_cam

    commit 之后在 ~/.ros/camera_info之中会创建一个标定参数文件。将其复制到usb_cam包中

    cp ~/.ros/camera_info/head_camera.yaml $(rospack find usb_cam)/launch/ov2610.yaml