http://www.52rd.com/S_TXT/2016_6/TXT85047.HTM?WebShieldDRSessionVerify=Wz3h6srvu76qRI4MFxK8

前面介绍了双camera能实现的功能中其中很大的一类都是依赖于景深的计算。现在这类功能在手机上的应用也是相对成熟的。在这类功能中景深的计算是很重要的,如何计算景深,计算的准确性和性能都是决定最后能够实现什么样功能的关键。

  很多人都会说其实我们从一张照片中也能看出哪个物体在前,哪个物体在后。这其实这是建立在我们大脑的一些视觉经验的基础上。比如近大远小,又比如物体影子的位置。这些经验确实很重要,但是在实际的计算机视觉中很难使用相同的方法,并且在很多情况即使人眼也没有办法分辨景深。比如说下面这个网上很热的图,哪个楼在前。

  还有下图这种情况,利用平面上的图像在特殊的视觉角度。造成人的虚假3D视觉。

  在仅仅从张图片中看在一条直线上的物体,很多不同距离的点再图片上映射的位置其实是一个。如下图的P和Q。光从照片无法得到距离信息。

  而在实际场景,人眼分辨景深主要是依靠双目视觉分辨景深。这和双camera分辨景深的原理一样。主要方法是依靠三角定位的方法如下图。不过需要注意的是,下面这个公式是基于两个平行的完全相同的camera实现的。

  从公式中可以得判断Z的距离中d和X的大小很关键.两个摄像头间的距离D很重要减少D的距离不仅会减少能测量的最大距离而且会减少相对景深间精度。而X的精度更多取决于像素的大小。在实际计算中不会小于一个像素。

  实际计算中有的时候会将最大和最小距离间分割成多个不同平面。每个平面之间的精度由算法的实际精度决定。这样可以较少一些在景深计算中误差导致的精度的问题。

  上面的公式是基于两个平行的相同camera的。但是实际使用的时候实际上有很多问题。比如在上图两个camera计算景深中总有一部分场景不能相交。因此实际的为了景深计算两个camera的FOV设计会不一样。主camera是用来取实际图的,副camera的图像主要是用来参考计算景深。副camera的FOV一般会大于主camera. 但是即使是这样距离较近的物体依然有可能不同时在两个camera图像当中。经过调整的计算景深范围的关系如下图。

  但是这么计算之后的问题是由于两个摄像头的成像和物体的放缩比不一样。因此这么做之后在计算距离的时候要考虑将图像的放缩比变换成一样。实际上不仅是放缩比,包括畸变和姿势差。这在计算景深的都是很重要的矫正。本篇文章不以校准和矫正为主要内容

  通过在左右两张图计算出不同点差异的图一般叫Disparity Map,这个图上表示的是两张图上相同点的位移差异,但是由于三角定位中的位移差异和Z成正比,因此很多时候Disparity Map 就直接被用作景深图。多数时候这个图是以灰度图的形式进行存储。

  下图是如何通关过 Disparity Map 重建3D场景的过程。

  计算景深的常用几个重要流程如下图。其中最后一步是用来3D重建,现在很多场景中并不单独使用。其中calibration和矫正是密切相关的,后面有机会我们可以单独讨论。本文主要讨论如何计算两张图的立体相关性这部分。

  另外一个实际问题从图上看我们找到X1和X2似乎很简单。但是在实际图中如何能找到两个相同的点呢?当然全图找可以,但是如果全图寻找类似点的话精度或者这个问题其实也是双camera算法计算景深中的最重要算法重要问题。在实际使用状况下两个相机的坐标无任何约束关系,相机的内部参数可能不同,甚至是未知的。要刻画这种情况下的两幅图像之间的对应关系,需要引入一个重要的概念对极几何(Epipolargeometry)。其中有两个重要的概念两个重要的概念——对极矩阵(EpipolarMatrix)和基本矩阵(FundamentalMatrix)。这中间是描述两个camera图像中点对应的规律的。

  多数算法在真正计算两张图之前首先要做的就是纠正两个camera图像的之间的对应关系。将极线纠正到平行,这样有利于后面的计算。

  根据对极几何和矫正之后的图片,我们可以得到如何去搜索对应的点方法。但是在对应的极线上怎么来判断点是一样呢?常用的类似相关系数,或者Lucas-Kanade算法更适合计算整张图之间的位移的差异。在计算两个点之间的差异并怒好用。在成像系统中如果想单独从两个点的值来判断两个点是否一样也是有一些问题要解决,不仅两个camera本身的成像上就有差异,而且即使同一个camera拍摄过程中也会有噪声影响。因此仅用一个像素很难正确的找到对应像素的,多数情况下还是要借助周边的像素信息。一种比较简单且常用的方法是使用一个windows去寻找差异比使用一个像素会更好一些。因为在一个windows中有更多的纹理和差异信息方便比较。再根据之前矫正之后的图片逐个去比较是否相似就好了。

  比较窗口里面的信息是否相同就可以使用很多图像匹配的方法了。比较简单的如计算像素亮度的SSD,绝对差等方法,也就是计算两块中相对的像素间的差值的平方或者绝对值。当然也可以用其它更加鲁棒的图像匹配算法,比如Opencv里面的RobustMatch算法。网上有文章大家可以自己找来看看。这里只是示意景深计算的过程。

  SSD计算公式如下:

  然后最简单的方法就是选择所有格子计算结果E最小的D作为差异。

  但是同时又有了新的问题。当W选取比较小的时候景深图的噪声依然很大,而W选取大的时候景深图在X,Y方向上的分辨率牺牲又比较大。如何选择W大小需要在实际使用中根据需求惊醒选择。下面是同一张图在W为3X3和20X20像素的时候计算的结果。

  即使是我们选择了一个较好的窗口,但是在很多情况就和下图一样得到的景深图依然不能十分满意。这是由于这个算法本身很多时候还有很多误判的时候。

  景深图的计算的改进和算法中的预处理,图像匹配算法,还有景深图的后处理都有关系。下面是一个传统景深图的算法和改进算法的比较。

  不过就和其它算法一样,计算景深也不止一种算法,在实际应用中的算法中经常会用很多不同的处理办法来解决不同的问题。有些改进办法是从源图的处理入手,有些是从处理之后的景深图进行改进,还有一些是利用滤波器,GPU,甚至机器学习的方法提高景深的计算速度和精度。下一篇中我们进一步的探讨一些简单的改进景深图计算的方法。

双camera景深计算 (1)的更多相关文章

  1. 双camera景深计算

    https://sanwen8.cn/p/2e41VC5.html 本文系微信公众号<大话成像>,知乎专栏< all in camera>原创文章,转载请注明出处. 接着上一篇 ...

  2. c语言数字图像处理(二):图片放大与缩小-双线性内插法

    图像内插 假设一幅大小为500 * 500的图像扩大1.5倍到750 * 750,创建一个750 * 750 的网格,使其与原图像间隔相同,然后缩小至原图大小,在原图中寻找最接近的像素(或周围的像素) ...

  3. css常见双栏和三栏布局

    左侧固定右侧自适应 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  4. Unity 基于Cinemachine计算透视摄像机在地图中的移动范围

    Unity中Cinemachine的基础功能介绍可详见之前写的博客: https://www.cnblogs.com/koshio0219/p/11820654.html 本篇的重点是讨论,在给定规则 ...

  5. POJ3352 Road Construction Tarjan+边双连通

    题目链接:http://poj.org/problem?id=3352 题目要求求出无向图中最少需要多少边能够使得该图边双连通. 在图G中,如果任意两个点之间有两条边不重复的路径,称为“边双连通”,去 ...

  6. 移动平台Unity3D 应用性能优化

    WeTest 导读 做了大概半年多VR应用了,VR由于双眼double渲染的原因,对性能的优化要求比较高,在项目的进展过程中,总结了一些关于移动平台上Unity3D的性能优化经验,供分享. 一.移动平 ...

  7. 随便说说 post-processing

    九月份一篇博都没更新,这段时间一直在unity的坑里爬不起来,感觉真的很绝望啊,仿佛对生活都失去了信心. 渲染问题并没有解决,目前方案只是减轻视觉冲突,降低违和感.项目AR产品也做的越来越艰难,开始经 ...

  8. 剖析虚幻渲染体系(15)- XR专题

    目录 15.1 本篇概述 15.1.1 本篇内容 15.1.2 XR概念 15.1.2.1 VR 15.1.2.2 AR 15.1.2.3 MR 15.1.2.4 XR 15.1.3 XR综述 15. ...

  9. shell面试题目总结

    1.如何理解shell脚本中第一行#!/bin/sh #!为特殊的表示符,其后是解释此脚本的shell的路径.此脚本使用/bin/sh进行解释执行. 2.如何向脚本传递参数. 脚本名字 参数1 参数2 ...

随机推荐

  1. 卡夫卡(kafka)

    1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic.发送消息.消费消息?3.如何书写Kafka程序?4.数据传输的事务定义有哪三种?5.Kafka判断一个节点是否活着有哪两个条件 ...

  2. GS与NGP通信(不断跟新)

  3. libevent(2)

    client.cpp // App02.cpp : 定义控制台应用程序的入口点. // #include <string.h> #include <errno.h> #incl ...

  4. fis3 部署手册

    为什么使用FIS3 项目上线一段时间后如果更新JS或CSS文件,而客户端已经对该文件缓存过了,那就有可能会无法及时更新而继续采用旧的JS或CSS文件,无法达到想要的效果. 处理类似情况最有效的解决方案 ...

  5. 为什么 Java ArrayList.toArray(T[]) 方法的参数类型是 T 而不是 E ?

    前两天给同事做 code review,感觉自己对 Java 的 Generics 掌握得不够好,便拿出 <Effective Java>1 这本书再看看相关的章节.在 Item 24:E ...

  6. ubuntu设置开机启动脚本

    rc.local脚本 rc.local脚本是一个ubuntu开机后会自动执行的脚本,我们可以在该脚本内添加命令行指令.该脚本位于/etc/路径下,需要root权限才能修改. 该脚本具体格式如下: #! ...

  7. 浅谈数据库并发控制 - 锁和 MVCC

    在学习几年编程之后,你会发现所有的问题都没有简单.快捷的解决方案,很多问题都需要权衡和妥协,而本文介绍的就是数据库在并发性能和可串行化之间做的权衡和妥协 - 并发控制机制. 如果数据库中的所有事务都是 ...

  8. <2014 05 14> Android平台下2D/3D开发攻略

    Android通过OpenGL包含了对高性能2D和3D图形的支持,尤其支持OpenGLES API.OpenGL是一个跨平台的图形API,提供了软件操作3D图形硬件的接口.OpenGLES是一个专用于 ...

  9. 第05章—Swagger2打造在线接口文档

    spring boot 系列学习记录:http://www.cnblogs.com/jinxiaohang/p/8111057.html 码云源码地址:https://gitee.com/jinxia ...

  10. Java 语言基础之函数

    函数的定义: 函数就是定义在类中的具有特定功能的一段独立小程序 函数也称为方法 函数定义格式: 修饰符 返回值类型 函数名(参数类型 形式参数1, 参数类型 形式参数2,...) { 执行语句; re ...