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

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

【实验目的】

       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>

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

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

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

相关文章

igraph的layout布局

做图论的社区检测&#xff0c;需要画图显示&#xff0c;用igraph可以进行可视化。 igraph有几个布局&#xff0c;分别如下&#xff1a; layout_with_dh &#xff1a; The Davidson-Harel layout algorithm Place vertices of a graph on the plane, according to the simulat…

113-Linux_安装c/c++开发库及连接mysql数据库

文章目录 一.安装c/c开发库二.连接mysql数据库三.用户的管理与授权 mysql数据库的安装 一.安装c/c开发库 安装开发c/c的库&#xff0c;命令&#xff1a;apt install libmysqlclient-dev 二.连接mysql数据库 #include<stdio.h> #include<mysql/mysql.h>void fun…

Python+Selenium4环境搭建

set集合 怎么把列表种相同的数据和不同的数据取出来 1.把列表转为set集合 2.按照集合的交集 selenium 自动化测试&#xff1a;自动化测试就是通过代码或者是工具模拟人的行为来进行对WEB&#xff08;APP&#xff09;来进行操作。 QTP (HP公司)&#xff1a;以录制回放的模式…

CSS进阶

01-复合选择器 定义&#xff1a;由两个或多个基础选择器&#xff0c;通过不同的方式组合而成。 作用&#xff1a;更准确、更高效的选择目标元素&#xff08;标签&#xff09;。 后代选择器 后代选择器&#xff1a;选中某元素的后代元素。 选择器写法&#xff1a;父选择器 …

学系统集成项目管理工程师(中项)系列19b_成本管理(下)

1. 成本估算 1.1. 编制完成项目活动所需资源的大致成本 1.2. 在设计阶段多做些额外的工作可能减少执行阶段和产品运行时的成本 1.3. 项目估算的准确性随着项目的进展而提高 1.3.1. 【19下选48】 1.4. 针对完成活动所需资源的可能成本进行的量化评估 1.5. 容易被忽视的主要…

华为pbr双出口外线,指定内网单个vlan绑定单个出口外线上网

公司两条外线&#xff0c;vlan 10用nat走上面转发出去上网&#xff0c;vlan 20 走下面那条外线出去nat上网 AR2&#xff1a; interface GigabitEthernet0/0/0 ip address 6.6.6.1 255.255.255.0 interface GigabitEthernet0/0/1 ip address 154.1.2.3 255.255.255.0 interface…

JavaScript通过js的方式来判断一个数奇偶性的代码

以下为通过js的方式来判断一个数奇偶性的程序代码和运行截图 目录 前言 一、通过js的方式来判断一个数奇偶性&#xff08;html部分&#xff09; 1.1 运行流程及思想 1.2 代码段 二、通过js的方式来判断一个数奇偶性&#xff08;js部分&#xff09; 2.1 运行流程及思想 2…

Linux操作系统如何查看CPU型号信息?一条命令搞定

Linux操作系统服务器如何查看CPU处理器信息&#xff1f;使用命令cat /proc/cpuinfo可以查看CPU详细信息&#xff0c;包括CPU核数、逻辑CPU、物理CPU个数、CPU是否启用超线程等&#xff0c;阿里云服务器网分享Linux服务器查看CPU信息命令&#xff1a; 目录 Linux服务器查看CPU…

2023年贵州省职业技能大赛“网络安全” 项目比赛任务书

2023年贵州省职业技能大赛“网络安全” 项目比赛任务书 三、竞赛任务书内容 &#xff08;一&#xff09;拓扑图 &#xff08;二&#xff09;A模块基础设施设置/安全加固&#xff08;200分&#xff09; 一、项目和任务描述&#xff1a; 假定你是某企业的网络安全工程师&…

【Linux】Linux安装Redis(图文解说详细版)

文章目录 前言第一步&#xff0c;下载安装包第二步&#xff0c;上传安装包到/opt下&#xff08;老规矩了&#xff0c;安装包在opt下&#xff09;第三步&#xff0c;解压安装包第四步&#xff0c;编译第五步&#xff0c;安装第六步&#xff0c;配置redis第七步&#xff0c;设置开…

迁移学习

迁移学习 什么是迁移学习 迁移学习【斯坦福21秋季&#xff1a;实用机器学习中文版】 迁移学习&#xff08;Transfer Learning&#xff09;是一种机器学习方法&#xff0c;它通过将一个领域中的知识和经验迁移到另一个相关领域中&#xff0c;来加速和改进新领域的学习和解决问…

“土狗”的季节,meme热潮回归

文/章鱼哥 出品/陀螺财经 meme代币的热度好像又回来了&#xff0c;两周前推出的PEPE创下了历史新高。尽管加密货币市场仍处于漫长熊市中&#xff0c;但人们似乎仍然对风险投资保有兴趣。 meme代币作为基于互联网模因的高波动数字资产&#xff0c;似乎没有太多实用性。它们的价格…

AI仿写软件-仿写文章生成器

AI仿写软件&#xff1a;高效出色的营销利器 作为互联网时代的营销人员&#xff0c;我们不仅需要品牌意识&#xff0c;还必须深谙营销技巧。万恶的时限压力使得我们不得不在有限的时间内输出更多的文本内容&#xff0c;以便吸引更多的关注。那么&#xff0c;如何解决这个问题呢…

基数树RadixTree

转自&#xff1a;基数树RadixTree - 知乎 1. 基数树概述 对于长整型数据的映射&#xff0c;如何解决Hash冲突和Hash表大小的设计是一个很头疼的问题。radix树就是针对这种稀疏的长整型数据查找&#xff0c;能快速且节省空间地完成映射。借助于Radix树&#xff0c;我们可以实现…

用chatgpt实现 java导出excel复杂表。

记录一次使用chatgpt解决实际问题的&#xff0c;需求是在页面添加一个订单导出excel的功能&#xff0c;订单编号、订单明细&#xff0c;相同订单编号合并单元格&#xff0c;模板如下 表头表尾不用说&#xff0c; 主要是表格内容部分&#xff0c;左边是订单编号&#xff0c;右边…

ChatGPT常见问题及其解决方法汇总

好久没有更新过技术类的文章了&#xff0c;希望本篇文章能够对你有所帮助&#xff0c;今天这篇博客将会把ChatGPT注册中可能遇到的问题彻头彻尾的讲一下&#xff0c;创作不易&#xff0c;如果感觉有帮助的话就动动你发财的小手点个收藏点个赞吧。如有需要转载请附上原文链接&am…

微软骚操作恶心Win10用户,上网得先看广告

IE 浏览器在几个月前被彻底禁用&#xff0c;预装了快30年的老古董也确实到了退役的时候。 而微软也早有准备&#xff0c;2015年随着 Win10 发布推出了 Microsoft Edge 浏览器。 2020年迁移到 Chromium 内核让其成为了主流浏览器之一。 和 Chromium 系其他浏览器一样支持扩展插…

Portraiture4最新版滤镜P图一键磨皮插件

今天coco玛奇朵给大家带来了一款ps磨皮插件&#xff0c;超级简单好用。Portraiture 滤镜是一款 Photoshop&#xff0c;Lightroom 和 Aperture 插件&#xff0c;DobeLighttroom 的 Portraiture 消除了选择性掩蔽和逐像素处理的繁琐的手工劳动&#xff0c;以帮助您在肖像修整方面…

TiDB实战篇-PD调度常见问题处理方法

常见的问题 调度产生和执行 常见的调度类型 参数调度的速度 调度典型场景 Leader分布不均匀监控 leader分布算法&#xff0c;每一个leader的size作为总和&#xff0c;还有TiKV的剩余空间等等。 可以手动设置权重。 分布不均衡处理 TiKV节点下线速度慢 TiKV下线速度慢解决方法 …

IntelliJ IDEA修改背景颜色大全(护眼绿等)设置注释颜色

一.IDEA默认有3种背景颜色 路径为File->settings->Editor->Color Scheme可以设置软件默认颜色&#xff0c;旁边的小齿轮添加颜色名字 二.IDEA扩展颜色&#xff08;护眼绿&#xff09; 第一种方法&#xff1a; IDEA设置一张背景图片,路径&#xff1a;File->Setti…