双目标定之张正友标定法数学原理详解matlab版

news2024/11/18 12:36:14

目录

前言

1.相机标定

1.1 双目视觉基本原理

1. 2 相机的四个坐标系

1.3 相机畸变与校正

2.1 相机标定

张正友友棋盘格标定法在matlab的实现


这一篇主要详细介绍标定原理和相机各个坐标系之间的关系为后续的定位测距和重建做基础

前言

最近重新整理了一下自己做过的双目项目,准备从零开始更新双目的相关知识

1.相机标定

相机标定是计算机视觉中的一个重要步骤,它用于确定相机内部参数和外部参数,以便准确地将二维图像坐标与三维世界坐标对应起来。

相机标定的目的是消除摄像机镜头畸变和确定相机的内部参数,包括焦距、主点位置和像素间距等。同时,还可以确定相机的外部参数,如相机的位置和朝向。

常用的相机标定方法有两种:基于标定板和基于特征点。

基于标定板的方法是使用已知尺寸和几何结构的平面标定板,通过拍摄不同位置和角度下的图像,推导出相机的内外参数。这种方法需要在标定板上布置一些特殊的标记点或者棋盘格,在图像中检测和识别这些点,进而进行标定。

基于特征点的方法是通过检测图像中的特征点(如角点、边缘点等),并与其对应的三维世界坐标建立映射关系,从而计算相机的内外参数。这种方法不需要特殊的标定板,只要能够提取到足够多的特征点就可以进行标定。

相机标定的结果可以用于各种计算机视觉任务,如目标检测、物体跟踪、三维重建等。它能够提高图像处理的精度和鲁棒性,使得计算机能够更准确地理解和处理图像数据。

1.1 双目视觉基本原理

相比于单目视觉系统,双目立体视觉系统可以得到图像的三维坐标信息,进而计算出目标物体的距离信息,且双目立体视觉系统的测量精度较高、效率较快,因而具有无可取代的优势。

双目立体视觉为减少像素匹配点的立体匹配运算过程,一般多借助平行于同一水平线的左右2个摄像头,从2个不同视角对同一时间、同一场景拍下一组图像,然后对左右图像中的特征匹配点进行匹配计算出图像的深度信息,建立图像的视差图,得到图像的三维坐标信息,最终根据公式转换得到实际距离,完成双目测距功能。双目立体视觉的基本原理如图1所示。

图1中,P(x,z)表示目标树种的位置坐标;P1(x1,f)表示左目图像中的目标树种投影点的位置坐标;P2(x2,f)表示右目图像中的目标树种投影点的位置坐标;f表示焦距;c1、c2分别表示左右两摄像头的光心;b表示两摄像头光心之间的距离,即基线,则三角关系式如式(1)所示。

                                                   

对三角关系式进行转换,即可得到所求距离z,如式(2)所示。

1. 2 相机的四个坐标系

相机成像系统中,共包含四个坐标系:世界坐标系、相机坐标系、图像坐标系、像素坐标系。对于这四个坐标系中之间的关系还不太明白成像原理的同学需要先查一查学习一下。

双目视觉模型如图1所示,使用世界坐标系(OwXwYwZw)、相机坐标系(OclXclYclZcl或OcrXcrYcrZcr)、图像坐标系(ODlXDlYDl或ODrXDrYDr)和像素坐标系(OlXlYl或OrXrYr)的相互变化来描述空间点到图像点的成像过程,世界坐标系中某一点P(X,Y,Z)在双目相机采集到的左右图像上的投影分别为Pl和Pr,OlOcl和OrOcr为分别为相机的成像平面与像素平面点的距离,即相机的焦距fl和fr。

由双目视觉模型可以得到4种坐标系的对应关系,其中世界坐标系(OwXwYwZw)下的坐标通过旋转矩阵R和平移向量T转换到相机坐标系(OclXclYclZcl)下的坐标表示,其关系式为

相机坐标系(OclXclYclZcl)下的坐标通过透视投影转换到图像坐标系(ODlXDlYDl)下的坐标,其关系式如式(2)所示,式(2)可以通过齐次变换为式(3)Xcl/f=Xcl/Zcl,Ycl/f=Ycl/Zcl   (2)

图像坐标系(ODlXDlYDl)下的坐标通过离散化转换到像素坐标系(OlXlYl)下的坐标,(ul,vl)表示像素坐标,单位为像素(pixel),其关系式为

将式(1)、式(3)和式(4)联立,可以确定世界坐标系(OwXwYwZw)和像素坐标系(OlXlYl)的关系为

1.3 相机畸变与校正

在相机采集图像产生畸变包括径向畸变和切向畸变,径向畸变主要是相机镜头的形状造成的,调节公式为

由于制造上的缺陷使相机在组装过程中产生切向畸变,切向畸变用2个额外参数P1和P2表示,调节公式为 采用Zhang Z Y[10]的棋盘标定法对双目相机标定

2.1 相机标定

张正友友棋盘格标定法在matlab的实现

打开Matlab 上方的工具栏APP,找到图像处理和计算机视觉下的Stereo Camera Calibration工具,打开并将分割后的图片导入

 设置参数,对于一般的相机选择2 Coefficients选项即可,对于大视场相机则选择3 Coefficients选项。拉线删除误差较大的画面:

 2.2 获取参数

在matlab控制台分别输入 stereoParams.CameraParameters1.IntrinsicMatrix 和stereoParams.CameraParameters2.IntrinsicMatrix 获得左右相机的参数,下边填写时请注意进行矩阵的转置

为了获取左相机的畸变系数:[k1, k2, p1, p2, k3],我们需要分别输入stereoParams.CameraParameters1.RadialDistortion 和 stereoParams.CameraParameters1.TangentialDistortion

分别输入 stereoParams.RotationOfCamera2 和 stereoParams 来获取双目的旋转矩阵和平移矩阵

将以上参数填写进stereoconfig.py文件里,注意转置

import numpy as np

# 双目相机参数
class stereoCamera(object):
    def __init__(self):
        # 左相机内参
        self.cam_matrix_left = np.array([   [479.6018,   -0.0769,  652.6060],
                                            [       0,  478.0229,  352.3870],
                                            [       0,         0,         1]
                                        ])
        # 右相机内参
        self.cam_matrix_right = np.array([  [489.9354,   0.2789,  641.6219],
                                            [       0,  487.9356,  354.5612],
                                            [       0,         0,         1]
                                        ])

        # 左右相机畸变系数:[k1, k2, p1, p2, k3]
        self.distortion_l = np.array([[-0.0791, 0.0309, -0.0009, -0.0004, -0.0091]])
        self.distortion_r = np.array([[-0.1153, 0.1021, -0.0011,  -0.0005,  -0.0459]])

        # 旋转矩阵
        self.R = np.array([ [1.0000,  0.0005, -0.0184],
                            [-0.0005,  1.0000, 0.0001],
                            [ 0.0184,  -0.0001,  1.0000]   
                            ])
        # 平移矩阵
        self.T = np.array([[121.4655], [0.2118], [0.5950]])
        # 焦距
        self.focal_length = 749.402 # 默认值,一般取立体校正后的重投影矩阵Q中的 Q[2,3]
        # 基线距离
        self.baseline = 121.4655 # 单位:mm, 为平移向量的第一个参数(取绝对值)

棋盘格图片自提

链接:https://pan.baidu.com/s/1W31fTtr6db8qgTevulWeMA 
提取码:ybca

觉得有帮助的朋友点点赞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1099609.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【单片机基础】使用51单片机制作函数信号发生器(DAC0832使用仿真)

文章目录 (1)DA转换(2)DAC0832简介(3)电路设计(4)参考例程(5)参考文献 (1)DA转换 单片机作为一个数字电路系统,当需要采集…

ICML2021 | RSD: 一种基于几何距离的可迁移回归表征学习方法

目录 引言动机分析主角(Principal Angle)表征子空间距离正交基错配惩罚可迁移表征学习实验数据集介绍 实验结果总结与展望 论文链接 相关代码已经开源 引言 深度学习的成功依赖大规模的标记数据,然而人工标注数据的代价巨大。域自适应&…

10种新型网络安全威胁和攻击手法

2023年,网络威胁领域呈现出一些新的发展趋势,攻击类型趋于多样化,例如:从MOVEit攻击可以看出勒索攻击者开始抛弃基于加密的勒索软件,转向窃取数据进行勒索;同时,攻击者们还减少了对传统恶意软件…

android U广播详解(二)

android U广播详解(一) 基础代码介绍 广播相关 // 用作单个进程批量分发receivers,已被丢弃 frameworks/base/services/core/java/com/android/server/am/BroadcastReceiverBatch.java // 主要逻辑所在类,包括入队、分发、结束…

Spacedrive:开源跨平台文件管理 | 开源日报 No.57

denoland/deno Stars: 91.2k License: MIT Deno 是一个简单、现代和安全的 JavaScript 和 TypeScript 运行时,使用 V8 引擎并用 Rust 构建。其主要功能包括: 默认情况下具有高度安全性,除非显式启用,否则无法访问文件、网络或环…

docker入门加实战—网络

docker入门加实战—网络 我们运行了一些容器,但是这些容器是否能够进行连通呢?那我们就来试一下。 我们查看一下MySQL容器的详细信息: 主要关注,Networks.bridge.IPAddress属性信息: docker inspect mysql # 或者过…

RT-Thread学习笔记(二):RT-Thread内核

RT-Thread内核 什么是RTOS?RTOS内核包含哪些内容?RT-Thread内核架构RT-Thread系统架构 RT-Thread内核文件RT-Thread系统启动流程RT-Thread 内核配置文件 什么是RTOS?RTOS内核包含哪些内容? RTOS(Real Time Operating System)指的…

PyTorch 深度学习之循环神经网络(基础篇)Basic RNN(十一)

0.Revision: DNN dense 重义层 全连接 RNN处理带有序列的数据 1. What is RNNs? linear layer 1.1 What is RNN? tanh (-1, 1) 1.2 RNN Cell in PyTorch 1.3 How to use RNNCell *先把维度搞清楚 多了一个序列的维度 2. How to use RNN 2.1 How to use RNN - numLayers…

nginx正反向代理,负载均衡

Nginx 正向代理,反向代理 ,负载均衡 Nginx有两种代理协议 七层代理(http协议) 四层代理(tcp/udp流量转发) 四层代理七层代理概念 四层代理 四层代理:基于tcp/ip协议层的转发代理方式&#…

grid网格布局,比flex方便太多了,介绍几种常用的grid布局属性

使用flex布局的痛点 如果使用justify-content: space-between;让子元素两端对齐,自动分配中间间距,假设一行4个,如果每一行都是4的倍数那没任何问题,但如果最后一行是2、3个的时候就会出现下面的状况: /* flex布局 两…

Android versionCode会变成指定数值加001、002、003等后缀

“活久见”—今天遇到个奇怪的问题,指定的versionCode最终在打包出来的apk中,versionCode变成(指定数值 00X的形式) 如下所示: 注:当前build.gradle中的versionCode为26 后来搜索代码,发现原来是这个配置导…

系统架构与Tomcat的安装和配置

2023.10.16 今天是学习javaweb的第一天,主要学习了系统架构的相关知识和原理,下载了web服务器软件:Tomcat,并对其进行了配置。 系统架构包括:C/S架构 和 B/S架构。 C/S架构: Client / Server(…

052:mapboxGL同一个图层,设置每个feature不同的颜色

第052个 点击查看专栏目录 本示例是介绍演示如何在vue+mapbox中同一个图层,设置每个feature不同的颜色。 这里的数据都是点,通过每个geojson数据的属性中color的值,来同通过get的方式将颜色值挂在到circle-color上。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实…

JavaFX:控件边框设置

JavaFX中控件的边框也可以进行设置。主要有两种方式,一种是Java方式,一种是CSS方式。 JavaFX中控件继承自Region类。setBorder方法用来设置边框属性。 // The border of the Region, which is made up of zero or more BorderStrokes, and zero // or …

Python制作PDF转Word工具(Tkinter+pdf2docx)

一、效果样式 二、核心点 1. 使用pdf2docx完成PDF转换Word 安装pdf2docx可能会报错,安装完成引入from pdf2docx import Converter运行也可能报错,可以根据报错提示看缺少那些库,先卸载pip uninstall xxx,使用pip install python-docx -i htt…

[架构之路-238]:目标系统 - 纵向分层 - 网络通信 - 网络规划与设计框架

目录 一、需求分析 二、网络规划与设计 三、逻辑网络设计 四、物理设计 五、分层网络设计 5.1 接入层交换机 5.2 汇聚层交换机 5.3 核心层交换机 六、网络存储技术 七、IPV6 八、综合布线系统 九、物联网 十、云计算 十一、云存储 一、需求分析 二、网络规划与设…

Hadoop3教程(十五):MapReduce中的Combiner

文章目录 (103)Combiner概述什么是CombinerCombiner有什么用处Combiner有什么特点如何自定义Combiner (104)Combiner合并案例实操如何从日志里查看Combiner如果不存在Reduce阶段,会发生什么自定义Combiner的两种方式 参…

error=‘Cannot allocate memory‘ (errno=12)

Bug信息 OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000080000000, 716177408, 0) failed; error=Cannot allocate memory (errno=12)Bug本质原因 服务器内存不足,Java程序无法启动 查看服务器剩余内存 free -h常用的解决思路 减小服务中对JVM的…

基于vue实现滑块动画效果

主要实现:通过鼠标移移动、触摸元素、鼠标释放、离开元素事件来进行触发 创建了一个滑动盒子,其中包含一个滑块图片。通过鼠标按下或触摸开始事件,开始跟踪滑块的位置和鼠标/触摸位置之间的偏移量。然后,通过计算偏移量和起始时的…

2023年10月工作经验及问题整理总结

目录 1.window自带的base64加密解密 2.ElementUI修改鼠标移动到表格的背景色 3.vscode保存时几万个eslint错误 4.Git 拉取Gitee仓库报错:“fatal: unable to access ": Failed to connect to 127.0.0.1 port 1080: Connection r... 4.1本地查看Git是否使用…