引言

这个系列将对手眼标定过程中的图片获取、相机标定原理、相机标定时间、罗德里格斯公式、手眼标定原理、手眼标定实践等内容进行讲解。今天先进行第一部分,即图片获取环节。

我们首先需要了解下realsense D435i这一款相机。

Realsense D435i

搭载2000万像素的RGB摄像头和3D传感器,有两种采样模式,分别可以以30帧每秒的速度提供1280*720分辨率的照片,以及90帧每秒速度提供848*480低分辨率照片。深度距离为0.1m到10m,视场角为85*58度,可以适应于大多数场景,应用于移动机器人或者操作型机器人上,可以充分发挥他的作用。同时它自带一个惯性测量单元,可以检测三个坐标轴的横滚、俯仰、偏航等姿态表换,并配合视觉信息完成六自由度跟踪控制。实际的图片就是下图这样的:

了解完相机,我们来看下怎么通过程序对相机进行控制,这里使用python语言进行代码编写,主要用到pyrealsense2这个模块。

pyrealsense2

在控制时,我们首先需要了解这样几个概念:

1、管道:指的就是我们的realsense相机,用来创建一个电脑与相机之间的通道;

2、流:由于相机有三个镜头,因此这个文件就是用来配置这些镜头模组相关的参数的;

3、其他的参数和说明可以见网址,这里详细介绍了各个函数的用法。

https://intelrealsense.github.io/librealsense/python_docs/_generated/pyrealsense2.html#module-pyrealsense2

我们以实际的例子来讲解

1、需要做的第一步就是创建一个管道对象rs.popeline

2、由于需要对镜头进行单独设置,因此需要得到参数配置的模板,即rs.config

3、然后需要对每个镜头进行设置,相机标定不需要使用彩色镜头,只需要左右两个普通的相机镜头,里面的参数详见

可以看到我们使用了第一个参数设置方式。

4、然后就可以通过pipeline.start来启动这个进程。

import cv2
import numpy as np
import pyrealsense2 as rs
pipeline = rs.pipeline() 
config = rs.config()
config.enable_stream(rs.stream.infrared, 1, 640, 480, rs.format.y8, 30)
config.enable_stream(rs.stream.infrared, 2, 640, 480, rs.format.y8, 30)
profile = pipeline.start(config)
prof1 = profile.get_device().query_sensors()[0]
prof1.set_option(rs.option.emitter_enabled,0)
prof1.set_option(rs.option.exposure,20000)
files_path = 'Carema_C_PIC/carema_L‘
k = 0
while True:
    frames = pipeline.wait_for_frames()

    ir_frame_left = frames.get_infrared_frame(1)
    ir_frame_right = frames.get_infrared_frame(2)

    ir_left_image = np.asanyarray(ir_frame_left.get_data())
    ir_right_image = np.asanyarray(ir_frame_right.get_data())

    images2 = np.hstack((ir_left_image, ir_right_image))
    cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
    cv2.imshow("RealSense", images2)
    key = cv2.waitKey(1)

    if key & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break
    if key & 0xFF == ord('s'):
        print(4)
        cv2.imwrite(f"{files_path}/{k}.png",ir_left_image)
        cv2.imwrite(f"{files_path}/{k}.png",ir_right_image)
        k = k+1

5、需要注意的是代码里的这一部分:

profile = pipeline.start(config)
prof1 = profile.get_device().query_sensors()[0]
prof1.set_option(rs.option.emitter_enabled,0)
prof1.set_option(rs.option.exposure,20000)

由于realsense是深度相机,其获取深度的方式是通过结构光的方式得到,因此需要发射红外线,然后再测量。这种方式对于深度测量有效,但是对于相机标定来说,则是非常不利的。当红外发射器开着的时候,在图片上,将得到一条条由红外导致的亮线,非常影响标定的结果。因此我们需要做的就是在相机标定的时候将红外发射器关掉。

但是目前在网上几乎找不到程序,因此通过阅读官方文档,我编写了上面的代码,见前面代码的前三行。代码第四行的作用是设置曝光。

最终得到了比较完美的成像效果:

May the force be with you!