双目视觉(一)双目视觉系统
系列文章:
- 双目视觉(一)双目视觉系统
- 双目视觉(二)双目匹配的困难和评判标准
- 双目视觉(三)立体匹配算法
- 双目视觉(四)匹配代价
- 双目视觉(五)立体匹配算法之动态规划全局匹配
- 双目视觉(六)U-V视差
- 【项目实战】利用U-V视差进行地面检测
- 【项目实践】U-V视差路面检测之动态规划
1.说说单目相机
在单目视觉中,是无法确定一个物体的真实大小,它可能很大很远,可能很近很小,例如上图中,P点和Q点为真实世界的3维点,但是它们在相机平面上都投影到了同一个点,这也就无法确定一个物体的真实尺寸,也就是所谓的失去了尺度信息。
说到这里,有些读者会问啦:为什么非得用双目相机才能得到深度?我闭上一只眼只用一只眼来观察,也能知道哪个物体离我近哪个离我远啊!是不是说明单目相机也可以获得深度?
在此解答一下:首先,确实人通过一只眼也可以获得一定的深度信息,不过这背后其实有一些容易忽略的因素在起作用:一是因为人本身对所处的世界是非常了解的(先验知识),因而对日常物品的大小是有一个基本预判的(从小到大多年的视觉训练),根据近大远小的常识确实可以推断出图像中什么离我们远什么离我们近;二是人在单眼观察物体的时候其实人眼是晃动的,相当于一个移动的单目相机,这类似于运动恢复结构(Structure from Motion, SfM)的原理,移动的单目相机通过比较多帧差异确实可以得到深度信息。
但是实际上,相机毕竟不是人眼,它只会傻傻的按照人的操作拍照,不会学习和思考。下图从物理原理上展示了为什么单目相机不能测量深度值而双目可以的原因。我们看到红色线条上三个不同远近的黑色的点在下方相机上投影在同一个位置,因此单目相机无法分辨成的像到底是远的那个点还是近的那个点,但是它们在上方相机的投影却位于三个不同位置,因此通过两个相机的观察可以确定到底是哪一个点。
2.如何确定尺度呢?
由于仅通过单张图像无法获得像素的尺度信息,那么怎么办呢?办法是有的,我们可以通过获得不同视角的图像,然后通过三角测量(Triangulation)(或三角化) 的方法来估计地图点的深度。
表示成我们熟悉的针孔相机模型:
在上图中,我们知道相机的内部参数(K1,K2),已知匹配的点对(x1,x2),相机的位姿(R,T),求X。那么其实质就是:
具体的推导:
1.通过针孔模型,我们知道单幅图像的投影方程,如果不了解相机模型,可以看这篇博客(针孔相机模型):
2.多幅图像的投影方程组合在一起:
3.将上面两式整理可以得到:
3.最后采用最小二乘法求解X,Y,Z。
代码实现:
//************************************
// Description: 根据左右相机中像素坐标求解空间坐标
// Method: uv2xyz
// Parameter: Point2f uvLeft
// Parameter: Point2f uvRight
// Returns: cv::Point3f
//************************************
cv::Point3d uv2xyz(cv::Point2d uvLeft,cv::Point2d uvRight,cv::Mat mLeftP,cv::Mat mRightP)
{// [u1] [xw] [u2] [xw]//zc1 *|v1| = Pl*[yw] zc2*|v2| = P2*[yw]// [ 1] [zw] [ 1] [zw]// [1 ] [1 ]//最小二乘法A矩阵cv::Mat A = cv::Mat(4,3,CV_64F);A.at<double>(0,0) = uvLeft.x * mLeftP.at<double>(2,0) - mLeftP.at<double>(0,0);A.at<double>(0,1) = uvLeft.x * mLeftP.at<double>(2,1) - mLeftP.at<double>(0,1);A.at<double>(0,2) = uvLeft.x * mLeftP.at<double>(2,2) - mLeftP.at<double>(0,2);A.at<double>(1,0) = uvLeft.y * mLeftP.at<double>(2,0) - mLeftP.at<double>(1,0);A.at<double>(1,1) = uvLeft.y * mLeftP.at<double>(2,1) - mLeftP.at<double>(1,1);A.at<double>(1,2) = uvLeft.y * mLeftP.at<double>(2,2) - mLeftP.at<double>(1,2);A.at<double>(2,0) = uvRight.x * mRightP.at<double>(2,0) - mRightP.at<double>(0,0);A.at<double>(2,1) = uvRight.x * mRightP.at<double>(2,1) - mRightP.at<double>(0,1);A.at<double>(2,2) = uvRight.x * mRightP.at<double>(2,2) - mRightP.at<double>(0,2);A.at<double>(3,0) = uvRight.y * mRightP.at<double>(2,0) - mRightP.at<double>(1,0);A.at<double>(3,1) = uvRight.y * mRightP.at<double>(2,1) - mRightP.at<double>(1,1);A.at<double>(3,2) = uvRight.y * mRightP.at<double>(2,2) - mRightP.at<double>(1,2);//最小二乘法B矩阵cv::Mat B = cv::Mat(4,1,CV_64F);B.at<double>(0,0) = mLeftP.at<double>(0,3) - uvLeft.x * mLeftP.at<double>(2,3);B.at<double>(1,0) = mLeftP.at<double>(1,3) - uvLeft.y * mLeftP.at<double>(2,3);B.at<double>(2,0) = mRightP.at<double>(0,3) - uvRight.x * mRightP.at<double>(2,3);B.at<double>(3,0) = mRightP.at<double>(1,3) - uvRight.y * mRightP.at<double>(2,3);cv::Mat XYZ = cv::Mat(3,1,CV_64F);//采用SVD最小二乘法求解XYZcv::solve(A,B,XYZ,cv::DECOMP_SVD);//std::cout<<"空间坐标为 = "<<std::endl<<XYZ<<std::endl;//世界坐标系中坐标cv::Point3d world;world.x = XYZ.at<double>(0,0);world.y = XYZ.at<double>(1,0);world.z = XYZ.at<double>(2,0);return world;
}
3.双目相机
上面讲了如何获得深度信息,一个相机可以通过获得不同视角的图像,然后通过三角测量计算深度,那么我们也可以添加另外一个相机在不同的位置拍摄同一个点,这样就和同一个相机在不同视角获得多幅图像等价了。
注:在左相机相机平面上的点,投影到右相机平面为一条直线,这也就是极线约束,本质上是点和线的映射关系。
如果能将左相机平面中的点,在右相机平面中找到其对应的点,我们就可以获得深度值,进一步计算出物体的3维点信息。
我们知道了:两个相机可以同过三角测量获得三维信息,那么就直接这样计算了吗?其实也可以,不过为了简便,我们通常需要将两个相机平面矫正到同一水平上。因为在矫正后的双目相机,我们搜索对应的匹配点的搜索空间也从2维变成了1维。
首先来看看,未校正前的左右相机的两个平面,(左平面和右平面不在同一水平面上)
再来看看,极线矫正之后的双目相机:两个相机平面位于同一水平面上。
接下来我们来计算深度。
对于矫正后的针孔相机模型(如下图),我们可以使用简单的相似三角形的原理,来计算其深度值。
首先,对于第一个相机坐标。
接下来,对于第二个相机坐标系。
- 这两个三角形如下:
- X可以表达为:
- 两个等式合并
- 深度Z:
- 首先,对于针孔相机模型,根据相似三角形原理可以得到如下:
- 将上面的公式变换一下:
- 当然,现在X'和Y‘的坐标系是在图像的正中间,而我们处理的图像的坐标系,相对于在图像正中间的坐标系,原点平移了 [cx,cy]T,也放缩了一定的倍数。
- 那么左相机的三维点X,Y就可以计算:
4.双目匹配
现在已知双目相机的左图和右图,而且已知左图的点(红色)pl = (xl; yl),那么怎么在右图找到匹配点pr = (xr; yr)
呢?step1:由于矫正后的双目相机的左图和右图的点,符合极线约束,即yr = yl,那么我们可以通过极线来缩减搜索区域。
step2:在极线上我们如何去匹配,发现这个点是否是我们要找的点呢?
我们可以通过扫描极线,比较右图中的块和左图中的块,找到和左图最相似的那个就OK了。
step3:如何判断哪个块最相似呢?
可以通过计算极线上的每个点匹配代价。
step4:得到匹配点后,通过匹配点的坐标得到视差d,然后根据视差值d,焦距f,j基线b,进一步计算深度值d
双目视觉系统:
参考:
https://www.cnblogs.com/zyly/p/9373991.html
双目视觉(一)双目视觉系统相关推荐
- 双目视觉 1 双目视觉的原理
首先我们讲解一下双目视觉中,我们只有两张二维的图片,我们的目的就是通过这两张二位的图片来构建出一个三维的模型,这就要求我们要通过两张图,推算出来一个图片没有展示出来的深度.深度的计算的原理如下 图片中 ...
- 港科大开源 | 基于事件的双目视觉里程计
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 1 摘要 本文提出了一种双目事件相机的视觉里程计方法.我们的系统遵循并行跟踪和建图的方法,建图模块以概 ...
- 示例程序:关于双目视觉,标定,立体匹配(视差算法),点云,双目三维重建的原理以及代码
Evision双目视觉 关于双目视觉的一些总结 说明 前言 相机模型 标定 视差算法:立体匹配 测量,三维重建 示例程序 参考文献 关于双目视觉的一些总结 说明 如果读者对于本文或者Evision程序 ...
- 基于双目视觉的移动机器人SLAM系统研究与设计
基于双目视觉的移动机器人SLAM系统 - Jake.cai 这篇是最近在做研究生开题答辩时做的整理,PPT和相关的思维导图我已经上传,题目和方向也是自己想的,在移动机器人SLAM技术方面我完全是小白 ...
- 白学立体视觉(1): 双目视觉
文章目录 前言 什么是双目视觉? 双目视觉的应用 总结 前言 小伙伴们,大家好,以前学习了新的知识,一段时间之后便忘得差不多了,经常被他人嘲讽: 你真是白学xxx了!.是啊,我确实是白学了(该打该打) ...
- 基于机器视觉无人平台自主导航避障系统(卓翼智能)
摘自:http://www.droneyee.cn/index.php?m=content&c=index&a=show&catid=82&id=36 看来有公司专门做 ...
- 科研教育「双目视觉技术」首选!维视MV-VS220双目立体视觉系统开发平台
NO.1产品背景 在最近大热的自动驾驶赛道,大疆采用新的技术路线--双目立体视觉.具体来说,它就是模拟人的视觉系统,通过两个临近摄像头所拍摄到的画面的视差,来还原出三维立体结构.不需要对海量数据进行标 ...
- 结构光系统标定(四)基于双目视觉的结构光系统标定
上一篇文章讲了基于多项式拟合的结构光系统标定,实际上就是将一系列待测的长度值,隐式地表达在一个多项式里面,通过拟合的方式去求出从相位计算三维坐标所需的参数.当然,这个名字是我自己取的,不一定准确. 这 ...
- 双目视觉系统的原理和设计
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 双目立体视觉是机器视觉的一种重要形式,它是基于视差原理并由多幅图像 ...
- [复现笔记]基于双目视觉和三维重构的三维书写系统
1. 前言 前段时间正好看到一位大神的博客 http://blog.csdn.net/onezeros/article/details/6110838 利用双目视觉来构建一个书写系统, 涉及到相机的标 ...
最新文章
- datagrid表头与内容不对应_斜线表头竟然如此简单,花上3分钟学习,从此告别低颜值报表...
- 如何手工删除AD RMS SCP?
- RSA加解密算法的Java实现
- php判断ip地址小程序
- Crypto API 学习笔记一
- jdk 安装_Jdk 安装使用教程
- 优先队列——二项队列(binominal queue)
- 【华为云技术分享】Batch Normalization (BN) 介绍
- 苦于E63没有秒表,网上找的不好用,就自己写个简单的
- 2.1 API : LogisticRegression
- 你整明白了吗?Linux Shell 中各种括号的作用 ()、(())、[]、[[]]、{}
- smbinning包:R语言下的分箱处理工具
- Java - Java Mail邮件开发(2)springboot +Java Mail + Html
- Dynamips--RIP协议分析的详细过程1--前期工作准备
- 【计算机网络】湖科大微课堂 笔记目录(完结)
- (P61)io流类库:字符串流
- Linux学习-man和Info
- 流量来了,去努力保护好你的系统
- 女程序员||想逃离的悲惨世界
- 利用matplotlib制作饼图
热门文章
- pyinstaller paddle项目
- R语言gganimate包创建散点图动画图(gif)、transition_states函数根据分组变量创建动图、shadow_wake函数配置动画的渐变效果(gradual falloff)拖尾效应
- U美出品||红妆 中式新娘造型欣赏
- what is spring boot
- Java代码审计之URL重定向
- ITERATE 语句
- python 不以科学计数法输出
- 嘉祥计算机学校电话号码,嘉祥县职业中专
- 汇编语言中各种移位指令的区别与联系
- error: error validating “deployment. yaml“: error validating data: apiVersion not set; if you choose