智能汽车实验二(视觉传感器标定)
实验二 视觉传感器标定(实验报告)
【实验目的】
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与世界坐标系的转换关系:
其中,Xw Zcuv1=su0u00svv0001xy1=su0u00svv0001f0000f000010XcYcZc1=su0u00svv0001f0000f000010RT01XwYwZw1 |
实际上,摄像机镜头成像并不是理想的透视成像,而是存在径向变形、偏心变形、薄棱镜变形等因素影响下产生不同程度的畸变。由于畸变因素作用,使空间点成像并不在线性模型描述的位置x,y,而是在受到镜头失真影响而偏移的平面坐标x',y'
。
x=x'+ ∆xy=y'+ ∆y
其中,∆x、∆y
为非线性畸变值,与像点在图像中的位置有关。一般镜头畸变同时存在径向畸变和切向畸变,切向畸变是由于透镜与摄像头传感器平面或图像平面不平行而产生的,多是由于透镜安装到镜头模组上的偏差导致,通常较小。实际应用中多只考虑径向畸变,径向畸变常用距图像中心径向距离的泰勒级数展开的前几项来表示:
∆x=x'-u0k1r2+k2r4+…∆y=y'-v0k1r2+k2r4+…
k1、k2
为非线性畸变参数,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,设置参数:
- 棋盘格的宽度和高度(两个方向的角点数量),根据实际情况设置。
<!-- Number of inner corners per a item row and column. (square, circle) -->
<BoardSize_Width>9</BoardSize_Width>
<BoardSize_Height>6</BoardSize_Height>
- 每格的宽度
单元格的宽度应设置为实际的毫米数。
<!-- The size of a square in some user defined metric system (pixel, millimeter)-->
<Square_Size>50</Square_Size>
- 选择输入方式
程序提供了3种输入方式。如果摄像机已连接电脑,可以使用input_camera方式。该方式只需要设置视频输入设备号,对于笔记本而言,通常0表示笔记本内置摄像头,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> 这里面是相片的标定,坐标为像素点 |
相关文章:

智能汽车实验二(视觉传感器标定)
实验二 视觉传感器标定(实验报告) 【实验目的】 1、了解开源图像处理库OpenCV的结构,掌握OpenCV的基本使用方法。 2、了解开源图像处理库OpenCV的基本模块功能,掌握常用图像处理方法。 3、掌握摄像机标定算法,学会使用…...

计算机网络:HTTP
目录 HTTP 是什么?HTTP 常见的状态码有哪些HTTP 常见字段有哪些参考资料 HTTP 是什么? HTTP 是超文本传输协议,也就是HyperText Transfer Protocol。 1. 「协议」 「协」字,代表的意思是必须有两个以上的参与者。「议」字&…...

Go 语言接口
Go 语言接口 Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。 实例 实例 /* 定义接口 */ type interface_name interface { method_name1 [return_type] method_name2…...

常用的intellij的快捷键
ctrlshiftspace(new 后面自动提示) ctrlshift/ (注释) itar后面tab (for循环) it后面ctrlj(很多智能代码生成) AltInsert(自动生成构造函数,get,set方法) ctrlaltt(自动生成try,catch) altenter(创建测试类和子类) ctrlshiftbackspace(最后编辑的地方) ctrl…...

Unity中的`SetPositionAndRotation()`
介绍 SetPositionAndRotation() 是Unity中的一个方法,用于同时设置物体的位置和旋转。它可以在不必分别调用 transform.position 和 transform.rotation 属性的情况下,直接设置物体的位置和旋转。 方法 以下是 SetPositionAndRotation() 方法的参数&a…...

API 接口的使用和功能
随着互联网的快速发展,API接口已经成为了现代开发中不可或缺的一部分。API接口可以让你的应用程序与其他应用程序、系统或服务进行数据交流和集成。如果你正在开发应用程序,那么最好的方法就是使用API接口来增强功能和性能。 我们的API接口是为您的应用…...

Vue插件
介绍 Vue插件是一种扩展Vue应用程序功能的方式。使用Vue插件,您可以在Vue应用程序中重复使用代码或添加新功能。更具体地说,Vue插件通常具有以下用途: 封装重复的功能或组件,以便在多个Vue组件中使用。 扩展Vue的核心功能并使其…...

C++好难(5):内存管理
这一节学完,我们 C嘎嘎 就算是正式入门了,但是之后的课还会更上一阶d(ŐдŐ๑) 继续坚持! 【本节目标】 1. C/C内存分布 2. C语言中动态内存管理方式 3. C中动态内存管理 4. operator new与operator delete函数 5. new和delete的实现原…...

vue-admin-template中vue动态路由不显示问题解决
使用的的是vue-admin-template,这是一个极简的 vue admin 管理后台,它只包含了 Element UI & axios & iconfont & permission control & lint,这些搭建后台必要的东西。需要根据自己的需求二次开发。 线上地址:vue-admin-tem…...

IP协议介绍
文章目录 一、IP协议的基本认识二、IP的协议头格式三、网段划分四、特殊的IP地址五、IP地址的数量限制六、私有IP地址和公网IP地址 一、IP协议的基本认识 IP在网络分层中属于网络层协议,传输层协议里的TCP协议解决的是可靠性问题,网络层协议里的IP协议能…...

将一个单体服务重构成微服务
将一个单体服务重构成微服务需要经过以下步骤: 1. 拆分服务:将单体服务拆分成多个小服务,每个服务只负责一个特定的功能。拆分的原则是将服务按照业务功能进行划分,每个服务都应该是相对独立的。 2. 设计API:为每个服务…...

SpringBoot项目如何打包成exe应用程序
准备 准备工作: 一个jar包,没有bug能正常启动的jar包 exe4j,一个将jar转换成exe的工具 链接: https://pan.baidu.com/s/1m1qA31Z8MEcWWkp9qe8AiA 提取码: f1wt inno setup,一个将依赖和exe一起打成一个安装程序的工具 链接:…...

一文读懂:客户管理系统平台是什么?有什么作用?
“客户管理系统平台是什么?” “客户管理系统平台有什么作用?在哪里可以应用?怎么用?” 经常可以听到企业内部关于客户管理系统平台的这些问题,本文将会为您一一解答: 一、客户管理系统平台是什么 顾名…...

Node.js 与 TypeScript
目录 1、什么是 TypeScript 2、运行TypeScript 3、TypeScript 在Node.js 生态中的情况 1、什么是 TypeScript TypeScript是一种流行的开源语言,由微软维护和开发。它受到了世界各地许多软件开发人员的喜爱和使用。 基本上,它是JavaScript的超集&…...

Python并发编程之进程理论
前言 本文将详细介绍进程相关概念。 进程和程序 计算机上的未运行的QQ、Wechat等都属于程序,但是一旦当这些程序运行起来的话,就可以被称为进程。因此可以如下定义程序和进程: 程序:就是存在硬盘上的一堆代码。 进程…...

超级详细的mysql数据库安装指南
MySql数据库 如果你的电脑是mac那么你看这位大佬的分享。 如果你的电脑是windows,参考下面的安装步骤。 一、下载mysql数据库? 进入MySQL官方网站(MySQL Community Downloads),按下图顺序点击 1、进入下载页面 2、…...

Java并发编程实践学习笔记(三)——共享对象之发布和异常
目录 1 公共静态变量逸出 2 非私有方法逸出私有变量 3 this引用逸出 4 构造函数中的可覆盖方法调用逸出 发布(publishing)一个对象的意思是:使对象能够在当前作用域之外的代码中使用。例如,将一个指向该对象的引用保存到其他代…...

Python学习之Image模块图片滤镜效果操作示例
前言 滤镜效果是图像处理中常用的一种技术,可以用来增强图像的视觉效果,实现不同的效果,比如增强对比度、饱和度、色彩等。滤镜效果可以帮助用户快速地调整图像的特性,从而使图像更加适合用户的需求。 Image模块对于图像处理的…...

Grafana 系列-统一展示-5-AWS Cloudwatch 仪表板
系列文章 Grafana 系列文章 👍️强烈推荐 强烈推荐使用 GitHub 上的 monitoringartist/grafana-aws-cloudwatch-dashboards 仪表板。该 repo 有一系列 AWS 资源的仪表板,包括但不限于: EC2EBSAPI GWAutoscalingBillingEKSLambdaLogsRDSS3…...

MySQL---控制流函数、窗口函数(序号函数、开窗聚合函数、分布函数、前后函数、头尾函数、其他函数)
1. 控制流函数 格式 解释 案例 IF(expr,v1,v2) 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2。 SELECT IF(1 > 0,正确,错误) ->正确 IFNULL(v1,v2) 如果 v1 的值不为 NULL,则返回 v1ÿ…...

一心报国的西工大网安人走出新手村
大二下学期5月5日晚上,西工大长安校区教学西楼,作为一名网安专业本科生,从大一便立志学好网安知识,报效祖国,却苦于没有优秀学习资源,就把这事儿拖到了大二,最近上了一门专业课,如同…...

如何安装oracle的sample schema
首先从如下的地址选择合适的版本进行下载 https://github.com/oracle-samples/db-sample-schemas/releases 如果是rac环境,最好是将这个数据库停掉,然后只启动一个instance,然后再开始安装 [Tue May 09 20:26:34][377951][oraclenshqae01adm…...

ChatGPT :国内免费可用 ChatGPT +Midjourney绘图
前言 ChatGPT(全名:Chat Generative Pre-trained Transformer),美国OpenAI 研发的聊天机器人程序 ,于2022年11月30日发布 。ChatGPT是人工智能技术驱动的自然语言处理工具,它能够通过理解和学习人类的语言来…...

女孩子转数据分析难吗?难在哪里?
对于数据分析,很多人乍一听会觉得没啥技术难度,是个适合女孩子的专业。我们面对很多零基础小白也是用通俗的语言来形容这个专业:一般是通过Excel或者power BI工具对数据进行分析,制作成可视化的报表给领导层,为公司业务…...

基于常用设计模式的业务框架
前言 做开发也有好几年时间了,最近总结和梳理自己在工作中遇到的一些问题,工作中最容易写出BUG的需求就是改造需求了。一个成熟的业务系统是需要经过无数次迭代而成的,也意味着经过很多开发人员之手,最后到你这里,大部…...

ubuntu重启ssh服务
一、开启ssh服务首先需要安装打开ssh服务的库: sudo apt-get install openssh-server 二、检查当前的ssh开启情况: ps -e |grep ssh 三、如果有sshd,则ssh-server已经启动;若仅有agent,则尚未启动; 开启ssh…...

【19】SCI易中期刊推荐——计算机 | 人工智能领域(中科院2区)
💖💖>>>加勒比海带,QQ2479200884<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉…...

Vue.js条件、循环语句
文章目录 条件语句v-ifv-elsev-else-ifv-show 循环语句v-for 指令v-for 迭代对象valuevalue ,keyvalue ,key,index v-for 迭代整数 条件语句 v-if 在元素 和 template 中使用 v-if 指令 <div id"app"><p v-if"seen">现在你看到我…...

Go语言学习查缺补漏ing Day4
Go语言学习查缺补漏ing Day4 一、掌握iota的使用 请看下面这段代码: package mainimport "fmt"const (a iota_bc "ReganYue"dd1e iotaf iota )func main() {fmt.Println(a, b, c, d, d1, e, f) }思考一下输出结果会是什么? …...

说服审稿人,只需牢记这 8 大返修套路!
本文作者:雁门飞雪 如果说科研是一场修炼,那么学术界就是江湖,投稿就是作者与审稿人或编辑之间的高手博弈。 在这一轮轮的对决中,有时靠的是实力,有时靠的是技巧,然而只有实力和技巧双加持的作者才能长久立…...