【ZED】从零开始使用ZED相机(四):双目相机标定(MATLAB+张氏标定法)

引言

【ZED】从零开始使用ZED相机导航:
【ZED】从零开始使用ZED相机(一):windows下的安装配置与测试
【ZED】从零开始使用ZED相机(二):打开相机+捕获图像
【ZED】从零开始使用ZED相机(三):相机标定(张氏标定法)
上一篇博客介绍了利用ZED相机捕获棋盘格图像(仅保存左图),并利用一系列的.py脚本实现了单目相机的标定,那么如何实现双目相机的标定?目前matlab软件就有现成的双目相机的标定方法,在自定义.py脚本实现双目标定之前(其实目前笔者还未实现)不妨先试试现有的标定软件(如果比较着急用的话)

1 安装MATLAB

MATLAB是一款商业数学软件,用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATLAB和Simulink两大部分,可以进行矩阵运算、绘制函数和数据、实现算法、创建用户界面、连接其他编程语言的程序等,主要应用于工程计算、控制设计、信号处理与通讯、图像处理、信号检测、金融建模设计与分析等领域。
直接附上安装的参考链接:https://mp.weixin.qq.com/s/LAatgqNf55zpxzOYlpn8fg

在这里插入图片描述

2 获取双目的棋盘格图像

这里笔者分享下标定图像,简单的直接打印棋盘格图像(如果需要更高的精度可能需要购买或者定制标定板)
链接:https://pan.baidu.com/s/199uPaKDCptc4rgG1wIg-wg?pwd=lian
提取码:lian
利用ZED的SDK以及自定的代码实现双目图像的捕获(代码和上篇博客基本一致,些许修改)

"""
2022.02.02
author:alian
ZED相机的二次开发:双目相机标定
"""
import pyzed.sl as sl
import cv2
import numpy as np

class CameraZed2:
    def __init__(self,resolution=None,fps=30,depthMode = None):
        self.zed = sl.Camera()
        self.input_type = sl.InputType()
        self.init_params = sl.InitParameters(input_t=self.input_type)
        # 设置分辨率
        if resolution == "2K":
            self.init_params.camera_resolution = sl.RESOLUTION.HD2K
        elif resolution == "1080":
            self.init_params.camera_resolution = sl.RESOLUTION.HD1080
        else:  # 默认
            self.init_params.camera_resolution = sl.RESOLUTION.HD720
        self.init_params.camera_fps = fps  # 设置帧率
        # 设置获取深度信息的模式
        if depthMode == "PERFORMANCE":
            self.init_params.depth_mode = sl.DEPTH_MODE.PERFORMANCE
        elif depthMode == "QUALITY":
            self.init_params.depth_mode = sl.DEPTH_MODE.QUALITY
        else:
            self.init_params.depth_mode = sl.DEPTH_MODE.ULTRA
        self.init_params.coordinate_units = sl.UNIT.MILLIMETER  # 单位毫米
        # 打开相机
        err = self.zed.open(self.init_params)
        if err != sl.ERROR_CODE.SUCCESS:
            print(repr(err))
            self.zed.close()
            exit(1)

        self.runtime = sl.RuntimeParameters()
        self.runtime.sensing_mode = sl.SENSING_MODE.STANDARD
        self.savepath = ''  # 标定图像保存的路径

    def grab_imgs(self):  # 捕获左右图像用于相机标定(文件夹自动创建)
        img_l = sl.Mat()
        img_r = sl.Mat()
        num = 0
        # 自动创建保存文件夹(分别存放左图和右图)
        import time
        name = time.strftime("%Y-%m-%d-%H-%M", time.localtime())
        self.savepath_L = './images/%s/L' % name
        self.savepath_R = './images/%s/R' % name
        os.makedirs(self.savepath_L,exist_ok=True)
        os.makedirs(self.savepath_R,exist_ok=True)


        while True:
            if self.zed.grab(self.runtime) == sl.ERROR_CODE.SUCCESS:
                self.zed.retrieve_image(img_l,sl.VIEW.LEFT)
                self.img_l = img_l.get_data()
                self.zed.retrieve_image(img_r,sl.VIEW.RIGHT)
                self.img_r = img_r.get_data()
                view = np.concatenate((self.img_l,self.img_r),axis=1)
                cv2.imshow('View',cv2.resize(view,(1920,540)))
                key = cv2.waitKey(1)
                if key & 0xFF == ord('s'):  # 按S同时保存左右图像
                    savePath_L = os.path.join(self.savepath_L, "L{:0>3d}.png".format(num))
                    print(savePath_L)
                    cv2.imwrite(savePath_L, self.img_l)
                    savePath_R = os.path.join(self.savepath_R, "R{:0>3d}.png".format(num))
                    cv2.imwrite(savePath_R, self.img_r)
                    num +=1
                if key & 0xFF == 27:  # 按esc退出视图窗口
                    break

调用函数:

if __name__ == "__main__":
    cam = CameraZed2(resolution='1080',fps=30)
    cam.grab_imgs()  # 获取标定图像(左、右图)

在这里插入图片描述
在这里插入图片描述

3 开始标定

首先打开MATLAB双目标定工具
在这里插入图片描述
分别选择左右图所在文件夹
在这里插入图片描述

在这里插入图片描述
进行角点检测
在这里插入图片描述
在这里插入图片描述
显示角点检测的结果
在这里插入图片描述
点击校正后显示如下:
在这里插入图片描述
导出校正后的参数:
在这里插入图片描述
在MATLAB主界面显示如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如上得到相机标定的参数,但是此次标定还是比较粗略的,笔者尝试几种不同的拍摄角度(固定相机,改变标定板的位姿),得到的标定误差都不一样,因此是否有更好的拍摄位姿?还需进一步研究。

4 标定板的尝试

打印的标定板用于测试还尚可,但是要获得准确的相机内外参数就远远不够了。实现高精度的标定板需要能够防止外界关对相机成像的影响,导致成像结果照片变黑或者反光,因此带有光源的背光板是最好的选择,打印上定制的棋盘格图案,但是越好的标定板也越贵,如铝基板一块可能就得上千了,
带有光源的背光板?ipad是不是可以作为显示棋盘格的背光板呢?并且还自带光源。于是笔者如下尝试如下:
在这里插入图片描述
需要注意的是,要先测量好单元格的尺寸,笔者测量的尺寸是20mm,接着按照上述的步骤进行标定,获得结果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
综上,利用MATLAB标定工具实现了双目相机的粗略标定,更加高精度的标定还需进一步研究。

  • 7
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
张氏标定是一种常用的摄像机标定方法,用于确定摄像机的内参和外参等参数,以提高摄像机测量的准确性。以下是关于张氏标定Matlab代码的解读。 首先,Matlab代码开始时会加载一些相关的库和函数,这些函数用于读取图像、创建相机对象等。 接着,代码会读取一组用于标定的图像,并对每一幅图像进行处理。通过调用相机对象的函数,可以获得图像的特征点。这些特征点可能是角点、棋盘格顶点或其他类型的特征点。 然后,代码会对特征点进行筛选和排序,以保证后续计算的准确性。这可以通过使用一些图像处理算和滤波器来实现。 接下来,代码会利用特征点的坐标信息,计算相机的内参和外参。通过优化算,可以得到相机的焦距、主点位置、畸变系数以及相机的旋转和平移矩阵等参数。 在计算完相机的内参和外参之后,代码会对标定结果进行评估。这可以通过计算重投影误差来实现,即将特征点的实际坐标重新投影到图像平面上,与原始特征点位置进行比较。 最后,代码会输出相机标定结果,包括内参矩阵、畸变系数、旋转矩阵和平移矩阵等。同时,还会提供一些评估指标,如平均重投影误差等,以衡量标定的准确性。 综上所述,张氏标定Matlab代码主要包含了读取图像、提取特征点、计算相机参数、评估标定结果等一系列步骤。通过这些步骤,能够精确地获得相机的内参和外参,从而提高摄像机测量的准确性。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值