相机的标定

文章目录

  • 相机的标定
      • 标定步骤
      • 标定结果
      • 影响因素
      • 参数分析
      • 精度提升
          • 一、拍摄棋盘格
          • 二、提升标定精度
      • 标定代码实现

相机的标定

双目相机的标定是确保它们能够准确聚焦和成像的关键步骤。以下是详细的标定步骤和可能的结果,同时考虑了不同光照条件和镜头光圈大小等因素对标定结果的影响。

标定步骤

  1. 准备标定板

    • 使用一个具有明显特征点的标定板,如棋盘格标定板。
    • 确保标定板平整且特征点清晰可辨。
  2. 固定相机位置

    • 将双目相机固定在稳定的三脚架或支架上。
    • 调整相机位置,确保标定板完全位于相机的视野内。
  3. 采集标定图像

    • 在不同的角度和距离下,移动标定板并拍摄多组图像(通常建议至少15组)。
    • 确保图像中标定板的特征点清晰可见。
  4. 使用标定软件

    • 可以使用OpenCV、MATLAB等提供的相机标定工具。
    • 导入拍摄的标定图像,并识别标定板上的特征点。
  5. 计算标定参数

    • 通过软件计算相机的内参(如焦距、主点坐标等)和外参(如旋转矩阵和平移向量)。
    • 同时,软件还会给出畸变系数等参数。
  6. 立体校正和验证

    • 使用标定参数进行立体校正,确保左右相机的图像在同一水平线上对齐。
    • 通过拍摄实际场景验证标定的准确性,观察立体匹配的效果。

标定结果

  • 标定参数:包括相机的内参(焦距、主点等)、外参(旋转矩阵、平移向量)和畸变系数。
  • 误差分析:标定软件通常会给出重投影误差等指标,用于评估标定的准确性。重投影误差越小,说明标定越准确。

影响因素

  1. 光照条件

    • 强光或弱光条件下,标定板的特征点可能不够清晰,影响标定的准确性。
    • 建议在均匀且适度的光照条件下进行标定。
  2. 镜头光圈大小

    • 光圈大小影响景深和图像亮度。过大或过小的光圈都可能导致标定板上的特征点模糊。
    • 选择适中的光圈大小,以获得清晰的标定图像。

综上所述,双目相机的标定是一个精确且细致的过程,需要考虑多种因素以确保标定的准确性。通过遵循上述步骤并注意影响因素,可以获得高质量的标定结果,从而实现双目相机的准确聚焦和成像。

角点的数量:如果标定板格子是12x9的,那么格点的数据则是11x8
像下面这幅图格点的数据就是11x8在这里插入图片描述

参数分析

以下是标定的结果,标定代码放在文末。

Calibration Error: 0.26985438768011444
Intrinsic Matrix:
 [[9.64900471e+04 0.00000000e+00 4.00956403e+02]
 [0.00000000e+00 9.84639627e+04 5.17965206e+02]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]
Distortion Coefficients:
 [-7.27106948e+00  4.02668787e-02 -2.75489644e-02 -1.58608135e-02
  2.25903054e-04]

这些参数通常与计算机视觉中的相机标定(Camera Calibration)相关。相机标定是确定相机的内部参数(内参)和畸变系数的过程,以便更准确地从图像中获取信息。下面我会解释这些参数的含义:

  1. Calibration Error:

    • Calibration Error: 0.26985438768011444 表示相机标定的误差。这个数值越小,说明标定越准确。误差是通过比较标定板上角点的实际图像坐标与通过标定参数计算得到的图像坐标之间的差异来计算的。
  2. Intrinsic Matrix:

    • 这个矩阵描述了相机的内部几何和光学特性,通常包含焦距(fx, fy)、主点(cx, cy)等参数。矩阵的形式一般为:

      [fx  0  cx]
      [ 0 fy cy]
      [ 0  0  1]
      

      在你给出的数据中:

      • fx = 9.64900471e+04fy = 9.84639627e+04 是相机在x和y方向上的焦距(以像素为单位)。
      • cx = 4.00956403e+02cy = 5.17965206e+02 是图像坐标系中相机的主点坐标。
      • 矩阵的第三行是标准形式,表示这是一个齐次坐标变换。
  3. Distortion Coefficients:

    • 这些系数用于纠正由于相机镜头畸变引起的图像变形。常见的畸变包括径向畸变和切向畸变。
    • 给出的数据中,有五个畸变系数:
      • k1 = -7.27106948e+00 通常是径向畸变的主要系数。
      • k2 = 4.02668787e-02, k3 = -2.75489644e-02 可能是径向畸变的高阶系数。
      • p1 = -1.58608135e-02, p2 = 2.25903054e-04 通常是切向畸变的系数。

通过这些参数,可以对相机拍摄的图像进行畸变校正,以及从图像坐标转换到真实世界坐标等。这在许多计算机视觉应用中,如三维重建、目标跟踪、机器人导航等,都是非常重要的。

在相机标定过程中,内参和外参是否会随着标定板的变化而变化,这个问题可以从两个方面来分析:

一、内参

  1. 内参是描述相机内部属性的参数,包括焦距、主点(光学中心)坐标、畸变系数等。
  2. 这些参数通常在相机标定时确定,并且对于特定相机型号是固定的,不随时间变化。
  3. 因此,内参不会随着标定板的变化而变化。无论标定板的形状、大小或位置如何改变,相机的内部属性如焦距、主点坐标等保持不变。

二、外参

  1. 外参是描述相机在世界坐标系中的位置和姿态的参数,包括旋转矩阵和平移向量。
  2. 这些参数与相机和标定板之间的相对位置关系密切相关。
  3. 当标定板的位置或方向发生变化时,相机的外参也会随之变化。例如,如果移动相机或更改拍摄角度,外参会随之调整以反映这些变化。
  4. 因此,外参会随着标定板的变化而变化。具体来说,当标定板与相机的相对位置或姿态发生改变时,需要重新进行标定以获取准确的外参。

三、畸变系数

  1. 畸变系数的定义

    • 畸变系数是描述相机镜头制造偏差等因素导致的成像失真系数,主要包括径向畸变系数和切向畸变系数。
    • 这些畸变系数是相机本身的固有属性,与相机的制造和组装过程有关。
  2. 标定板的作用

    • 标定板在相机标定过程中主要用于提供已知的几何特征(如棋盘格的角点),以便通过图像处理算法来估计相机的内外参数和畸变系数。
    • 标定板的变化可能包括其位置、方向或图案的变化。
  3. 畸变系数与标定板的关系

    • 虽然标定板用于估计畸变系数,但畸变系数本身并不会因为标定板的变化而变化。
    • 畸变系数是相机镜头的固有特性,与标定板无关。标定板只是用于测量和估计这些系数的工具。
  4. 实验观察与结论

    • 在实际标定过程中,可能会观察到畸变系数的估计值随着标定板的不同设置(如不同位置、角度或图案)而有所差异。然而,这种差异主要是由于标定过程中的误差、图像噪声或算法的不稳定性引起的,并非畸变系数本身发生了变化。
    • 因此,可以归纳出结论:畸变系数不会随着标定板的变化而变化。它们是相机的固有属性,只与相机的镜头质量和组装工艺有关。

综上所述,

内参是相机的固有属性,不会因标定板的变化而改变;而外参则与相机和标定板之间的相对位置关系密切相关,当这种关系发生变化时,外参也需要相应地进行调整。

畸变系数是相机的固有特性,不会因标定板的变化而改变。标定板只是用于测量和估计这些系数的工具,而估计值的差异主要来源于标定过程中的各种误差和不确定性。

精度提升

一、拍摄棋盘格

为获得最佳效果,请使用至少10到20张包含校准图案的图像。 校准器至少需要三个图像。 尽量使用未压缩或压缩损失很小的图像格式(如png或bmp)。 为了更高的校准精度你需要:

  • 获取一部分你所关注的距离处的棋盘格图片,比如你要测量2米远的物体,那么请将棋盘放在距离相机2米左右的地方拍摄一部分图片

  • 棋盘表面和相机成像平面的夹角必须小于45度

不要修改图像,比如对其进行剪切

不要使用自动聚焦模式或改变图像的放大倍率

以相对于相机的不同方向拍摄棋盘图像

尽量采集各种不同的棋盘图像。镜头的畸变从图像中心径向增加,并且有时在图像各帧上表现不均匀, 为了获取图像的畸变信息,棋盘应当处在图像的各种不同边缘处

确保棋盘图案在左右两幅图像中都能被完整的显示

在每一对图像中尽量保持棋盘静止,也就是在同一时间拍摄。 若棋盘在两幅图像中发生了相对运动,会对标定精度产生负面影响

若想对远距离的重建获得更高的精度,需要将两个相机的距离调整的更大。

二、提升标定精度

添加或删除图像

添加图像:

  • 少于10张图像时
  • 棋盘没有覆盖足够的图像帧时
  • 棋盘与相机的相对方向变化不够多时

删除图像:

  • 删除具有较大重投影误差的图像
  • 删除太模糊的图像
  • 删除棋盘平面与相机平面夹角超过45度的图像

标定代码实现

import cv2
import numpy as np
import glob


def main():
    # 参数设置
    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
    w, h = 11, 8  # 棋盘格内角点数量(亲自数)
    objp = np.zeros((w * h, 3), np.float32)
    objp[:, :2] = np.mgrid[0:w, 0:h].T.reshape(-1, 2)

    # 存储角点信息
    objpoints = []  # 三维世界坐标
    imgpoints = []  # 二维图像坐标

    # 加载并处理图像
    images = glob.glob('data/d2/*.jpg')
    for fname in images:
        img = cv2.imread(fname)
        # img = cv2.resize(img, (768, 1024))  # 统一图像大小
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # gray = cv2.GaussianBlur(gray, (11, 11), 0)  # 滤波处理

        # 寻找棋盘格角点
        ret, corners = cv2.findChessboardCorners(gray, (w, h), None)

        if ret:
            corners = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria)  
            # 亚像素级角点检测
            m = [c[0] for c in corners]

            objpoints.append(objp)
            imgpoints.append(corners)

            # 可视化和保存结果
            cv2.drawChessboardCorners(img, (w, h), corners, True)
            cv2.imshow('Corners Found', img)
            cv2.waitKey(100)
            # 根据需要保存图像,这里以序号命名
            cv2.imwrite(f"result/mm_{len(imgpoints)}.jpg", img)
        else:
            print(f"Calibration failed for image: {fname}")

    cv2.destroyAllWindows()

    # 相机标定
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, (768, 1024), None, None)

    # 输出标定结果
    print("Calibration Error:", ret)
    print("Intrinsic Matrix:\n", mtx)
    print("Distortion Coefficients:\n", dist.ravel())
    # 如果需要,可以保存或进一步处理旋转向量和平移向量
    # print("Rotation Vectors:\n", rvecs)
    # print("Translation Vectors:\n", tvecs)


if __name__ == '__main__':
    main()

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

怎样去掉卷子上的答案并打印

当面对试卷答案的问题时,一个高效而简单的方法是利用图片编辑软件中的“消除笔”功能。这种方法要求我们首先将试卷拍摄成照片,然后利用该功能轻松擦除答案。尽管这一方法可能需要些许时间和耐心,但它确实为我们提供了一个可行的解决途径。 然…

Docker网络介绍

网络是虚拟化技术中最复杂的部分,也是Docker应用中的一个重要环节。 Docker中的网络主要解决容器与容器、容器与外部网络、外部网络与容器之间的互相通信的问题。 这些复杂情况的存在要求Docker有一个强大的网络功能去保障其网络的稳健性。因此,Docker…

windows10远程桌面端口,Windows 10远程桌面端口修改的两个方法

在Windows 10系统中,远程桌面功能允许用户通过网络从一台计算机远程访问和控制另一台计算机。默认情况下,远程桌面服务使用的端口是3389。然而,出于安全考虑,许多管理员和用户希望修改这一默认端口。本指南将详细介绍如何在Window…

柯桥商务英语培训|老外和你说Tom和Jack,可不是在说人名!所以是啥意思?

小明和小李,这两个人在中国相信没有谁不认识他们了。而且有关他们的梗更是传遍大街小巷。 例如:小明他爷爷活了103岁,小明做数学题,又或者是小李的老婆比小明小2岁等等。 其实在国外,也有这么两个人像小明、小李一样&a…

WPF/C#:显示分组数据的两种方式

前言 本文介绍自己在遇到WPF对数据进行分组显示的需求时&#xff0c;可以选择的两种方案。一种方案基于ICollectionView&#xff0c;另一种方案基于IGrouping。 基于ICollectionView实现 相关cs代码&#xff1a; [ObservableProperty] private ObservableCollection<Peo…

【mysql】常用操作:维护用户/开启远程/忘记密码/常用命令

一、维护用户 1.1 创建用户 -- 语法 > CREATE USER [username][host] IDENTIFIED BY [password];-- 例子&#xff1a; -- 添加用户user007&#xff0c;密码123456&#xff0c;并且只能在本地可以登录 > CREATE USER user007localhost IDENTIFIED BY 123456; -- 添加用户…

利用第三方服务对目标进行被动信息收集防止被发现(web安全白帽子)

利用第三方服务对目标进行被动信息收集防止被发现&#xff08;web安全白帽子&#xff09; 1 被动信息收集1.1 信息收集内容1.2 信息用途 2 信息收集-DNS2.1 DNS信息收集NSLOOKUP2.1.1 ping2.1.2 nslookup 2.2 DNS信息收集-DIG&#xff08;此命令查到的结果更复杂些&#xff0c;…

java中实现Callable方式创建线程

一、为啥要引入Callable 在前面讲了通过继承Thread和实现Runnable方式创建线程的区别&#xff0c;那为什么有了Runnable还要引入Callable?下面通过实现Runnable方式的弊端给出答案 实现Runnable方式的弊端&#xff1a; package java.lang; FunctionalInterface public inte…

C++基础知识——《缺省参数》和《函数重载》

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

pwn1_sctf_2016

首先找到后门 32位IDA 打开 这里fgets,他限定了位数,我们无法利用溢出 但是我们可以看见 最后还有个操作 他把我们里面的I,全部替换为了 you S大小为0x3c ---意思我们要输入0x3c/3 的I 能达到溢出的目的 再加上4 from pwn import * ghust remote("node5.buuoj.cn&q…

如何解决跨区域文件传输存在的安全管控问题?

⼤型企业和集团为扩⼤市场份额、优化资源配置&#xff0c;会在不同地区设⽴多级下属分⽀机构、研发中心、实验室等&#xff0c;存在研发数据横向或纵向流转的需求&#xff0c;研发数据进行跨区域文件传输的场景。跨区域可能是网络区域&#xff0c;也可能是地理区域&#xff0c;…

渗透测试-若依框架的杀猪交易所系统管理后台

前言 这次是带着摸鱼的情况下简单的写一篇文章&#xff0c;由于我喜欢探究黑灰产业&#xff0c;所以偶尔机遇下找到了一个加密H币的交易所S猪盘&#xff0c;我记得印象是上年的时候就打过这一个同样的站&#xff0c;然后我是通过指纹查找其它的一些站&#xff0c;那个站已经关…

【深度学习】实现基于MNIST数据集的TensorFlow/Keras深度学习案例

基于TensorFlow/Keras的深度学习案例 实现基于MNIST数据集的TensorFlow/Keras深度学习案例0. 什么是深度学习&#xff1f;1. TensorFlow简介2. Keras简介3. 安装TensorFlow前的注意事项4. 安装Anaconda3及搭建TensorFlow环境1&#xff09; 下载安装Anaconda Navigator2&#xf…

c++ 内存分析模型、引用

一、内存模型分区 内存四区的意义&#xff1a; 不同区域存放的数据&#xff0c;赋予不同的生命周期&#xff0c;给我们更大的灵活编程 &#xff08;一&#xff09;程序运行前 在程序编译后&#xff0c;生成了exe可执行程序&#xff0c;未执行程序前分为两个区域 代码区&…

C++ 89 之 string查找和替换

#include <iostream> #include <string> using namespace std;int main() { // int find(const string& str, int pos 0) const; //查找str第一次出现位置,从pos开始查找 // int find(const char* s, int pos 0) const; //查找s第一次出现位置,从pos开始查找…

【单片机毕业设计选题24020】-全自动鱼缸的设计与应用

系统功能: &#xff08;1&#xff09;检测并控制鱼缸水温&#xff0c;水温低于22℃后开启加热&#xff0c;高于28℃后关闭加热。 &#xff08;2&#xff09;定时喂食&#xff0c;每天12点和0点喂食一次&#xff0c;步进电机开启后再关闭模拟喂食。 &#xff08;3&#xff09…

路由器基础配置以及静态路由配置

1、搭建网络 搭建网络拓扑、分配IP地址、划分网段、连接端口 2、配置路由器 路由器基础配置 //进入全局配置模式 Router#enable Router#conf t Enter configuration commands, one per line. End with CNTL/Z.//配置高速同步串口serial2/0 Router(config)#int ser2/0 Route…

动手学深度学习(Pytorch版)代码实践 -卷积神经网络-27含并行连结的网络GoogLeNet

27含并行连结的网络GoogLeNet import torch from torch import nn from torch.nn import functional as F import liliPytorch as lp import matplotlib.pyplot as pltclass Inception(nn.Module):# c1--c4是每条路径的输出通道数def __init__(self, in_channels, c1, c2, c3, …

JDK19特性

JDK19特性 一、JAVA19概述 JDK 19 2022 年 9 月 20 日正式发布以供生产使用,非长期支持版本。不过,JDK 19 中有一些比较重要的新特性值得关注。 JDK 19 只有 7 个新特性: JEP 405: Record Patterns(记录模式)[1] (预览)JEP 422: Linux/RISC-V Port[2]JEP 424: Foreign …

Eclipse快捷键大全

CtrlK 参照选中的Word快速定位到下一个 CtrlE 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示) Ctrl/(小键盘) 折叠当前类中的所有代码 Ctrl(小键盘) 展开当前类中的所有代码 CtrlSpace 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的…