智能汽车实验二(视觉传感器标定)

news2024/9/23 4:31:45

实验二 视觉传感器标定(实验报告)

【实验目的】

       1、了解开源图像处理库OpenCV的结构,掌握OpenCV的基本使用方法。

       2、了解开源图像处理库OpenCV的基本模块功能,掌握常用图像处理方法。

       3、掌握摄像机标定算法,学会使用OpenCV进行摄像机标定。

【实验性质】

验证性实验。

【实验要求】

       1、C++集成开发环境(QT5或VS2015及以上)

       2、OpenCV 4.x

       3、单/双目摄像机

【实验内容】

       1、掌握OpenCV开源图像库的基本使用方法

       2、使用OpenCV进行单目摄像机标定

       3、使用OpenCV进行双目摄像机标定

【实验步骤】

       1、下载、安装、OpenCV 4.x

       官网下载:https://opencv.org/opencv-4-6-0/

      

       2、摄像机标定原理

摄像机标定的目标,是要建立三维世界坐标系与二维图像坐标系之间的对应关系。在单目视觉中,这种对应关系是一对多的,即二维图像中的一个像素点对应着三维空间中的一条直线;在双目视觉中,可以通过两幅二维图像上的对应像素点计算得到三维世界坐标系与二维图像坐标系的一一对应关系。由此便可以得到物体的三维坐标值。

摄像机安装位置参数为外部参数,摄像机镜头畸变参数为非线性模型内部参数。标定过程即是求出摄像机的内部参数和外部参数,从而得到上述坐标转换的旋转矩阵和平移向量。

图2-1 摄像机成像模型

图中,摄像机坐标系为OXcYcZc,而计算机图像坐标系O0uv与图像平面坐标系O1xy的转换关系为:

u = sux + u0

v = svy + v0

写成矩阵形式为:

uv1=su0u00svv0001xy1

其中,su、sv分别为x、y轴方向单位长度对应的像素点数;u0、v0为镜头光学中心位置,单位为mm。

请用矩阵形式写出计算机图像平面坐标系O0uv与世界坐标系的转换关系:

其中,XwYwZw为世界坐标系,R为3X3阶方阵;T为3X1维平移向量矩阵。

Zcuv1=su0u00svv0001xy1=su0u00svv0001f0000f000010XcYcZc1=su0u00svv0001f0000f000010RT01XwYwZw1

实际上,摄像机镜头成像并不是理想的透视成像,而是存在径向变形、偏心变形、薄棱镜变形等因素影响下产生不同程度的畸变。由于畸变因素作用,使空间点成像并不在线性模型描述的位置x,y,而是在受到镜头失真影响而偏移的平面坐标x',y'

x=x'+ ∆xy=y'+ ∆y

其中,∆x∆y为非线性畸变值,与像点在图像中的位置有关。一般镜头畸变同时存在径向畸变和切向畸变,切向畸变是由于透镜与摄像头传感器平面或图像平面不平行而产生的,多是由于透镜安装到镜头模组上的偏差导致,通常较小。实际应用中多只考虑径向畸变,径向畸变常用距图像中心径向距离的泰勒级数展开的前几项来表示:

∆x=x'-u0k1r2+k2r4+…∆y=y'-v0k1r2+k2r4+…

k1k2为非线性畸变参数,r2=x'-u02+y'-v02

摄像机的标定方法很多,大致可分为传统标定技术和自标定技术。

传统标定技术:     需要在摄像机前放置一个特定的标定物,并人为地提供一组已知坐标的特征基元,摄像机通过寻找这些已知特征的基元来实现标定                                              

自标定技术:      比较灵活,不需要特定的参照物,它利用环境的刚体性,通过对比多幅图像中的对应点来计算摄像机模型                      

OpenCV采用介于传统标定方法和自标定方法之间的一种方法,由张正友提出。这种方法不需要知道摄像机运动的具体信息,比传统标定方法更灵活,同时仍需要一个特定的标定物以及一组已知的特征基元的坐标,这一点不如自标定灵活。它通过在至少3个不同的位置获取标定物的图像,计算出摄像机所有的内外参数。

标定算法描述参考知乎:https://zhuanlan.zhihu.com/p/36371959

OpenCV源码在其sample/data目录下面一个自带的棋盘图(chessboard.png),显示如下:

    在标定的时候,算法要求提供的棋盘格的宽度与高度,还有他们的间隔距离。需要特别注意是这里的宽高是指他们的内部交叉点的个数,以上图为例,它的大小为7x7而不是8x8。间隔是指棋盘格之间的距离,可以用像素距离表示,也可以用实际毫米为单位表示。

       3、标定常用函数

(1)findChessboardCorners()

bool findChessboardCorners( InputArray image, Size patternSize, OutputArray corners,

            int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE );

       函数功能:  确定输入图像是否是棋盘模式,并确定角点的位置。如果所有角点都被检测到且它们都被以一定顺序排布(一行一行地,每行从左到右),函数返回非零值,否则在函数不能发现所有角点或者记录它们地情况下,函数返回0                             

(2)cv::drawChessboardCorners()

drawChessboardCorners( InputOutputArray image, Size patternSize,

                           InputArray corners, bool patternWasFound );

       函数功能:    用于标定摄像机时绘制被成功标定的角点                                       

   

(3)find4QuadCornerSubpix()

       find4QuadCornerSubpix(InputArray img, InputOutputArray corners, Size region_size );

       函数功能:   查找棋盘角的亚像素精确位置。尝试近似分隔棋盘格字段(“四边形”)的线并返回这些线的交叉点。                                                     

(4)cornerSubPix()

       void cornerSubPix( InputArray image, InputOutputArray corners, Size winSize,

                       Size zeroZone, TermCriteria criteria );

       函数功能:      优化角点位置,获得棋盘格上的亚像素角点。                                                    

(5)calibrateCamera()

       double calibrateCamera( InputArrayOfArrays objectPoints,

                            InputArrayOfArrays imagePoints,

                            Size imageSize,

                            InputOutputArray cameraMatrix,

                            InputOutputArray distCoeffs,

                            OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs,

                            int flags = 0,

                            TermCriteria criteria = TermCriteria(TermCriteria::COUNT +

                            TermCriteria::EPS, 30, DBL_EPSILON) );

       函数功能:   通过多个视角的2D/3D对应,求解出该相机的内参数和每一个视角的外参数                                                      

(6)initUndistortRectifyMap()

       void initUndistortRectifyMap(InputArray cameraMatrix,

                                InputArray distCoeffs,

                                InputArray R,

                                InputArray newCameraMatrix,

                                Size size,

                                int m1type,

                                OutputArray map1,

                                OutputArray map2)

       函数功能:    这个函数使用于计算无畸变和修正转换关系。                                                       

       4、单目摄像机标定

(1)打开标定配置参数文件default.xml,设置参数:

  1. 棋盘格的宽度和高度(两个方向的角点数量),根据实际情况设置。

      <!-- Number of inner corners per a item row and column. (square, circle) -->

      <BoardSize_Width>9</BoardSize_Width>

     <BoardSize_Height>6</BoardSize_Height>

  1. 每格的宽度

单元格的宽度应设置为实际的毫米数。

  <!-- The size of a square in some user defined metric system (pixel, millimeter)-->

  <Square_Size>50</Square_Size>

  1. 选择输入方式

程序提供了3种输入方式。如果摄像机已连接电脑,可以使用input_camera方式。该方式只需要设置视频输入设备号,对于笔记本而言,通常0表示笔记本内置摄像头,1表示外置摄像头。

  1. 编译OpenCV标定程序

(2)标定程序将实现以下功能

  • 确定失真矩阵
  • 确定摄像机矩阵
  • 摄像机、视频和图像文件列表的输入
  • 从XML/YAML文件进行配置
  • 将结果保存到XML/YAML文件中
  • 计算重投影误差

程序只有一个参数。其配置文件的名称。如果没有,它将尝试打开一个名为“default.xml”。

(3)运行标定程序,摄像机将拍摄25幅图片并识别角点,如下图

(4)标定结果保存在程序中指定的结果文件中

    请在实验报告中说明结果文件中各项数据的意义(阅读代码,并在网上查阅相关资料)

<nr_of_frames>25</nr_of_frames>

图像的宽和高度

<image_width>640</image_width>

<image_height>480</image_height>

棋盘格的宽度11和高度8

<board_width>11</board_width>

<board_height>8</board_height>

单元格的尺寸

<square_size>50.</square_size>

相机类型

<fisheye_model>0</fisheye_model>

尺寸自适应

<fix_aspect_ratio>1.</fix_aspect_ratio>

相机内部参数矩阵data为值

Rows 和 cols为行和列

Dt表示数据类新

<camera_matrix type_id="opencv-matrix"><rows>3</rows><cols>3</cols>

<dt>d</dt>

<data> 7.0111172389870558e+02 0. 3.1950000000000000e+02 0. 7.0111172389870558e+02 2.3950000000000000e+02 0. 0. 1.

</data></camera_matrix>

畸变系数

Row和cols为维度

Data包含畸变系数实际的值

<avg_reprojection_error>

为平均投影误差值

<distortion_coefficients type_id="opencv-matrix"><rows>5</rows><cols>1</cols>

<dt>d</dt>

<data> 7.2399710954221264e-02 4.5114674802590399e-01 0. 0. -3.8163393536623835e+00</data></distortion_coefficients><avg_reprojection_error>4.1946356118960665e-01</avg_reprojection_error>

<extrinsic_parameters type_id="opencv-matrix"><rows>25</rows><cols>6</cols>

数据类型为double

<dt>d</dt>

<data>

数据太长这里省略

</data>

<image_points type_id="opencv-matrix">

<rows>25</rows><cols>88</cols>

数据类型为浮点

<dt>"2f"</dt>

<data>1.96974991e+02 3.05226959e+02 2.15540726e+02 3.04309814e+02 2.34028198e+02 3.03369354e+02 2.52492340e+02 3.02424805e+02 2.70655762e+02 3.01588440e+02 2.88653290e+02 3.00733093e+02 3.06717133e+02 2.99980408e+02 3.24438385e+02 2.99227295e+02 3.42079742e+02 2.98437469e</data>

这里也是数据太长省略

<grid_points> 0. 0. 0. 50. 0. 0. 100. 0. 0. 150. 0. 0. 200. 0. 0. 250. 0. 0. 300. 0. 0. 350. 0. 0. 400. 0. 0. 450. 0. 0. 500. 0. 0. 0. 50. 0. 50. 50. 0. 100. 50. 0. 150. 50. 0. 200. 50. 0. 250. 50. 0. 300. 50. 0. 350. 50. 0. 400. 50. 0. 450. 50. 0. 500. 50. 0. 0. 100. 0. 50. 100. 0. 100. 100. 0. 150. 100. 0. 200. 100. 0. 250. 100. 0. 300. 100. 0. 350. 100. 0. 400. 100. 0. 450. 100. 0. 500. 100. 0. 0. 150. 0. 50. 150. 0. 100. 150. 0. 150. 150. 0. 200. 150. 0. 250. 150. 0. 300. 150. 0. 350. 150. 0. 400. 150. 0. 450. 150. 0. 500. 150. 0. 0. 200. 0. 50. 200. 0. 100. 200. 0. 150. 200. 0. 200. 200. 0. 250. 200. 0. 300. 200. 0. 350. 200. 0. 400. 200. 0. 450. 200. 0. 500. 200. 0. 0. 250. 0. 50. 250. 0. 100. 250. 0. 150. 250. 0. 200. 250. 0. 250. 250. 0. 300. 250. 0. 350. 250. 0. 400. 250. 0. 450. 250. 0. 500. 250. 0. 0. 300. 0. 50. 300. 0. 100. 300. 0. 150. 300. 0. 200. 300. 0. 250. 300. 0. 300. 300. 0. 350. 300. 0. 400. 300. 0. 450. 300. 0. 500. 300. 0. 0. 350. 0. 50. 350. 0. 100. 350. 0. 150. 350. 0. 200. 350. 0. 250. 350. 0. 300. 350. 0. 350. 350. 0. 400. 350. 0. 450. 350. 0. 500. 350. 0.</grid_points></opencv_storage>

<grid_points>

这里面是相片的标定,坐标为像素点

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

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

相关文章

Xilinx 7系列FPGA内置ADC

Xilinx 7系列FPGA全系内置了一个ADC&#xff0c;称之为XADC。这个XADC&#xff0c;内部是两个1mbps的ADC&#xff0c;可以采集模拟信号转为数字信号送给FPGA内部使用。 XADC内部可以直接获取芯片结温和FPGA的若干供电电压&#xff08;7系列不包括VCCO&#xff09;&#xff0c;用…

麒麟KylinV10SP1(2203)推荐安装一些硬件监控类软件与使用

目录 前言 1、tlp 电源管理 &#xff08;1&#xff09;查看电池容量、使用量、为Thinkpad设定电池充电开始结束阈值 &#xff08;2&#xff09;查看硬盘比如NVME SSD的型号种类、当前温度、读写量等信息&#xff1b; &#xff08;3&#xff09;查看CPU型号以及频率上下限、…

软件测试简单么,发展前景如何?

随着人工智能时代的到来&#xff0c;IT行业受到了越来越多人的重视。软件测试作为把控软件质量必不可少的环节&#xff0c;其重要性可见一斑。 软件测试可以说是算得上IT行业里相对简单的语言&#xff0c;但是也只是相对哈&#xff0c;如果想学习下去还是要看个人的学习能力的…

软件测试工作内容和职责有哪些

目前&#xff0c;在IT行业中测试的职位数量仅次于开发&#xff0c;可以说是第二大技术就业岗位。然而许多人对测试师工作的理解还停留在&#xff0c;只需要像用户一样使用产品&#xff0c;然后发现有问题提交报告就行了。其实这是极其不准确的&#xff0c;软件测试师在测试产品…

通过Dnspy调试解决powershell使用Install-module指定的转换无效的问题

之前运行Install-module -Name NtObjectManager出现以下错误&#xff1a; PackageManagement\Install-Package : Package NtObjectManager failed to be installed because: 指定的转换无效。 At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.…

Shell编程之排序

目录 一、冒泡排序 二、选择排序 三、插入排序 基本思想&#xff1a; 四、反转排序 基本思想&#xff1a; 五、睡眠排序 六、希尔排序 基本思想&#xff1a; 举例 一、冒泡排序 冒泡排序&#xff0c;该排序的命名非常形象&#xff0c;即一个个将气泡冒出。冒泡排序一…

ChatDOC工具——使用ChatGPT高效阅读技术科研论文

ChatDOC是一款功能强大的人工智能阅读辅助工具&#xff0c;专为帮助用户快速理解论文内容而设计。使用ChatDOC&#xff0c;您可以通过上传PDF版论文文献&#xff0c;利用先进的ChatGPT技术&#xff0c;只需三个简单步骤&#xff0c;便可以高效地阅读论文&#xff0c;提高阅读效…

TypeScript初识

目录 介绍 定义 优点 类型声明 ts文件编译选项 自动编译 编译选项的各个属性 include compilerOptions 介绍 定义 TS&#xff08;TypeScript&#xff09;是一种由微软开发的编程语言&#xff0c;它是 JavaScript 的一个超集&#xff0c;提供了静态类型检查、类、接…

Linux系统编程——多线程[中]:互斥与同步

0.关注博主有更多知识 操作系统入门知识合集 目录 1.并发过程中的问题 2.互斥 2.1互斥锁 2.2如何看待互斥锁 2.3加锁和解锁的本质 2.4对锁做一个封装 2.5可重入函数与线程安全 2.6死锁 3.同步 3.1条件变量 1.并发过程中的问题 我们知道&#xff0c;同一个进程中的…

【SpringBoot】过滤器,监听器,拦截器介绍

文章目录 一、简介1、过滤器2、拦截器3、监听器 二、如何创建1、过滤器2、监听器3、拦截器 三、总结 一、简介 通过两幅图我们可以理解拦截器和过滤器的特点 1、过滤器 过滤器是在请求进入tomcat容器后&#xff0c;但请求进入servlet之前进行预处理的。请求结束返回也是&…

模拟IC与数字IC设计该怎么选?哪个岗位薪资高?

很多同学想要入行IC&#xff0c;但不知道数字和模拟方向怎么选&#xff1f; 如果没有亲身体会过模拟设计&#xff0c;并有发自内心的自信或者兴趣&#xff0c;一般不看好纯小白去学模拟电路设计。 模拟设计想做好&#xff0c;没有数学功底&#xff0c;没有电路分析的功底&…

面试题30天打卡-day24

1、Redis 为什么快&#xff1f; Redis 之所以快&#xff0c;主要是因为它具有以下特点&#xff1a; 纯内存操作&#xff1a;Redis 的数据存储在内存中&#xff0c;因此读写速度非常快&#xff0c;而无需像传统数据库一样从硬盘读取和写入数据。与此同时&#xff0c;Redis 支持…

【算法】动态规划算法求(编辑距离)

目录 编辑距离&#xff1a; 举例&#xff1a; 代码如下 调试&#xff1a; 核心代码&#xff1a; 画图演示上述代码&#xff1a; 编辑距离&#xff1a; 是一种计算两个自符串之间差异程度的方法&#xff0c;它通过比较两个字符串之间的插入&#xff0c;删除和 替换操作的数…

深度神经网络模型部署——Docker学习

容器技术中有三个核心概念&#xff1a;容器&#xff08;Container&#xff09;、镜像&#xff08;Image&#xff09;&#xff0c;以及镜像仓库&#xff08;Registry&#xff09; 从本质上来说&#xff0c;容器属于虚拟化技术的一种&#xff0c;和虚拟机&#xff08;Virtual Mac…

CentOS7安装vsftpd

CentOS7安装vsftpd 最近又用到ftp了&#xff0c;摸索了一下终于安装成功&#xff0c;记录下安装过程&#xff0c;本次使用的操作系统为 CentOS7&#xff0c;ftp使用vsftpd。 安装vsftpd yum install -y vsftpd配置vsftpd vsftpd的配置文件路径为&#xff1a;/etc/vsftpd/vs…

软件测试基础面试题大全(上)

1. 软件生命周期是什么&#xff1f; 软件生命周期&#xff1a;需求调研&#xff08;可行性研究&#xff09;、需求分析&#xff08;需求规格说明书&#xff09;、设计&#xff08;系统架构、模块设计、表结构设计、接口设计等&#xff0c;产出概要设计文档和详细设计文档&…

表达式求值问题-双栈模板化实现

好久不见&#xff0c;真的很久都没有更新博客了&#xff0c;最近很多事情&#xff0c;所以比较忙碌&#xff0c;没有时间每天都学算法&#xff0c;但是我会挤时间尽量做到&#xff0c;每两三天就更新博客&#xff0c;我会努力的&#xff0c;加油~ 前言&#xff1a;计算器都见过…

加码本地生活、成为“万能入口”,抖音完成了百度曾经的梦想

文|螳螂观察 作者| 小别 前有美团点评&#xff0c;后有阿里巴巴&#xff0c;本地生活服务从来就不平静。 并没有在最好的时间出发的抖音&#xff0c;还是顺着短视频的内容优势&#xff0c;从团购、本地游、外卖再到近期推出商城频道&#xff0c;逐步完善了本地生活服务的布局…

浅谈jmeter性能测试步骤入门

一、Jmeter简介 1 概述 jmeter是一个软件&#xff0c;使负载测试或业绩为导向的业务&#xff08;功能&#xff09;测试不同的协议或技术。 它是 Apache 软件基金会的Stefano Mazzocchi JMeter 最初开发的。 它主要对 Apache JServ&#xff08;现在称为如 Apache Tomca…

linux命令文本命令之~~~ sort ~~ tr ~~cut ~~ uniq

目录 一. sort命令二. uniq 命令三. tr命令四. cut命令 一. sort命令 以行为单位对文件内容进行排序&#xff0c;也将他根据不同的数据类型来排序 比较原则是从首字符向后&#xff0c;依次按ASCII码进行比较&#xff0c;最后按照升序输出排序 语法格式&#xff1a; sort 【选…