精华内容
下载资源
问答
  • 双目测距原理

    万次阅读 多人点赞 2019-05-28 16:16:42
    双目测距基本原理双目测距实际操作分4个步骤:相机标定——双目校正——双目匹配——计算深度信息。 相机标定:摄像头由于光学透镜的特性使得成像存在着径向畸变,可由三个参数k1,k2,k3确定;由于装配方面...

    双目测距基本原理:

    双目测距实际操作分4个步骤:相机标定——双目校正——双目匹配——计算深度信息。

    相机标定:摄像头由于光学透镜的特性使得成像存在着径向畸变,可由三个参数k1,k2,k3确定;由于装配方面的误差,传感器与光学镜头之间并非完全平行,因此成像存在切向畸变,可由两个参数p1,p2确定。单个摄像头的定标主要是计算出摄像头的内参(焦距f和成像原点cx,cy、五个畸变参数(一般只需要计算出k1,k2,p1,p2,对于鱼眼镜头等径向畸变特别大的才需要计算k3))以及外参(标定物的世界坐标)。而双目摄像头定标不仅要得出每个摄像头的内部参数,还需要通过标定来测量两个摄像头之间的相对位置(即右摄像头相对于左摄像头的旋转矩阵R、平移向量t)。

    双目校正:双目校正是根据摄像头定标后获得的单目内参数据(焦距、成像原点、畸变系数)和双目相对位置关系(旋转矩阵和平移向量),分别对左右视图进行消除畸变和行对准,使得左右视图的成像原点坐标一致(CV_CALIB_ZERO_DISPARITY标志位设置时发生作用)、两摄像头光轴平行、左右成像平面共面、对极线行对齐。这样一幅图像上任意一点与其在另一幅图像上的对应点就必然具有相同的行号,只需在该行进行一维搜索即可匹配到对应点。
    双目匹配:双目匹配的作用是把同一场景在左右视图上对应的像点匹配起来,这样做的目的是为了得到视差图。双目匹配被普遍认为是立体视觉中最困难也是最关键的问题。得到视差数据,通过上述原理中的公式就可以很容易的计算出深度信息。

     

     

    双目摄像机的物理机构

    网上大部分人都写了这一点,也仿佛只有这一点有写的价值和物理意义。
    这里本来想放个控件(可调节动画),一直弄不上来,就算了。需要的可以联系我要下,下面放两张图片。

    在这里插入图片描述

    图中可以得出的结论
    1.深度变化(EG*EF/(AB+CD)或者H到EF的距离),会导致AB,CD和AB+CD的变化,这里不过多强调AB,CD的变化,只讨论AB+CD,这个原因后边会提到。当深度变大时,AB+CD逐渐变小。
    从公式(公式看不懂没关系,它只是我推导的,大家也可以自己推一下,推导是三角形的比例关系)
    AC=EF-AB-DC
    设Z为深度
    那么AC/EF=(Z-EG)/Z
    这样就可以推导出来了。
    在这里插入图片描述

    从这个图我们就可以明显看出只要我们的深度不变,那么我们的AB+CD也就不会改变,可以看出,深度和单独的AB与CD没有直接关系,而只与两者的和有关。

    AB+CD 与同一距离的 视差 是想等的。  

    AB + DC = XR - XT  

    注意此处 AB DC 用向量相加  (AB + DC =  =  (Bx-Ax)+ (Cx - Dx)   【Bx 为左图像的中点x, Dx为右图像的中点x  Ax,Cx为两幅图同一特征点的x坐标】

    XR - XT = XRx - XTx  (XRx 与 XTx 分别是两幅图同一特征点的x坐标)

    备注:此处的公式都是假设摄像头是水平的,如果摄像头垂直,应该使用 y 坐标。

     

    单目测距原理:

    先通过图像匹配进行目标识别(各种车型、行人、物体等),再通过目标在图像中的大小去估算目标距离。这就要求在估算距离之前首先对目标进行准确识别,是汽车还是行人,是货车、SUV还是小轿车。准确识别是准确估算距离的第一步。要做到这一点,就需要建立并不断维护一个庞大的样本特征数据库,保证这个数据库包含待识别目标的全部特征数据。比如在一些特殊地区,为了专门检测大型动物,必须先行建立大型动物的数据库;而对于另外某些区域存在一些非常规车型,也要先将这些车型的特征数据加入到数据库中。如果缺乏待识别目标的特征数据,就会导致系统无法对这些车型、物体、障碍物进行识别,从而也就无法准确估算这些目标的距离。

    单/双目方案的优点与难点

    从上面的介绍,单目系统的优势在于成本较低,对计算资源的要求不高,系统结构相对简单;缺点是:(1)需要不断更新和维护一个庞大的样本数据库,才能保证系统达到较高的识别率;(2)无法对非标准障碍物进行判断;(3)距离并非真正意义上的测量,准确度较低。

    双目检测原理:

    通过对两幅图像视差的计算,直接对前方景物(图像所拍摄到的范围)进行距离测量,而无需判断前方出现的是什么类型的障碍物。所以对于任何类型的障碍物,都能根据距离信息的变化,进行必要的预警或制动。双目摄像头的原理与人眼相似。人眼能够感知物体的远近,是由于两只眼睛对同一个物体呈现的图像存在差异,也称“视差”。物体距离越远,视差越小;反之,视差越大。视差的大小对应着物体与眼睛之间距离的远近,这也是3D电影能够使人有立体层次感知的原因。
     

    上图中的人和椰子树,人在前,椰子树在后,最下方是双目相机中的成像。其中,右侧相机成像中人在树的左侧,左侧相机成像中人在树的右侧,这是因为双目的角度不一样。再通过对比两幅图像就可以知道人眼观察树的时候视差小,而观察人时视差大。因为树的距离远,人的距离近。这就是双目三角测距的原理。双目系统对目标物体距离感知是一种绝对的测量,而非估算。

    理想双目相机成像模型

    根据上述推导,要求得空间点P离相机的距离(深度)z,必须知道:
    1、相机焦距f,左右相机基线b(可以通过先验信息或者相机标定得到)。
    2、视差 :,即左相机像素点(xl, yl)和右相机中对应点(xr, yr)的关系,这是双目视觉的核心问题。

     

    重点来看一下视差(disparity),视差是同一个空间点在两个相机成像中对应的x坐标的差值,它可以通过编码成灰度图来反映出距离的远近,离镜头越近的灰度越亮; (前提是两个摄像头是水平,如果两颗摄像头是垂直的,则使用y坐标的差值)

     

    极线约束

    对于左图中的一个像素点,如何确定该点在右图中的位置?需要在整个图像中地毯式搜索吗?当然不用,此时需要用到极线约束。
    如上图所示。O1,O2是两个相机,P是空间中的一个点,P和两个相机中心点O1、O2形成了三维空间中的一个平面PO1O2,称为极平面(Epipolar plane)。极平面和两幅图像相交于两条直线,这两条直线称为极线(Epipolar line)。
    P在相机O1中的成像点是P1,在相机O2中的成像点是P2,但是P的位置是未知的。我们的目标是:对于左图的P1点,寻找它在右图中的对应点P2,这样就能确定P点的空间位置。
    极线约束(Epipolar Constraint)是指当空间点在两幅图像上分别成像时,已知左图投影点p1,那么对应右图投影点p2一定在相对于p1的极线上,这样可以极大的缩小匹配范围。即P2一定在对应极线上,所以只需要沿着极线搜索便可以找到P1的对应点P2。
     

    非理性情况:

    上面是两相机共面且光轴平行,参数相同的理想情况,当相机O1,O2不是在同一直线上怎么办呢?事实上,这种情况非常常见,因为有些场景下两个相机需要独立固定,很难保证光心完全水平,即使固定在同一个基板上也会由于装配的原因导致光心不完全水平,如下图所示:两个相机的极线不平行,并且不共面。

    这种情况下拍摄的两张左右图片,如下图所示。

    左图中三个十字标志的点,右图中对应的极线是右图中的三条白色直线,也就是对应的搜索区域。我们看到这三条直线并不是水平的,如果进行逐点搜索效率非常低。

    图像矫正技术

    图像矫正是通过分别对两张图片用单应性矩阵(homography matrix)变换得到,目的是把两个不同方向的图像平面(下图中灰色平面)重新投影到同一个平面且光轴互相平行(下图中黄色平面),这样转化为理想情况的模型。


    经过图像矫正后,左图中的像素点只需要沿着水平的极线方向搜索对应点就可以了。从下图中我们可以看到三个点对应的视差(红色双箭头线段)是不同的,越远的物体视差越小,越近的物体视差越大。

    上面的主要工作是在极线上寻找匹配点,但是由于要保证两个相机参数完全一致是不现实的,并且外界光照变化和视角不同的影响,使得单个像素点鲁棒性很差。所以匹配工作是一项很重要的事情,这也关系着双目视觉测距的准确性。

    双目视觉的工作流程

    相机镜头畸变校正原理及方法,之前介绍过,这个基本是通用的,可以用张正友校准法。


    双目测距的优点与难点

    从上面的介绍看出,双目系统优势:(1)成本比单目系统要高,但尚处于可接受范围内,并且与激光雷达等方案相比成本较低;(2)没有识别率的限制,因为从原理上无需先进行识别再进行测算,而是对所有障碍物直接进行测量;(3)直接利用视差计算距离,精度比单目高;(4)无需维护样本数据库,因为对于双目没有样本的概念。

    双目系统的难点:

    (1)计算量非常大,对计算单元的性能要求非常高,这使得双目系统的产品化、小型化的难度较大。所以在芯片或FPGA上解决双目的计算问题难度比较大。国际上使用双目的研究机构或厂商,绝大多数是使用服务器进行图像处理与计算,也有部分将算法进行简化后,使用FPGA进行处理。

    (2)双目的配准效果,直接影响到测距的准确性。

    2.1、对环境光照非常敏感。双目立体视觉法依赖环境中的自然光线采集图像,而由于光照角度变化、光照强度变化等环境因素的影响,拍摄的两张图片亮度差别会比较大,这会对匹配算法提出很大的挑战。

    2.2、不适用于单调缺乏纹理的场景。由于双目立体视觉法根据视觉特征进行图像匹配,所以对于缺乏视觉特征的场景(如天空、白墙、沙漠等)会出现匹配困难,导致匹配误差较大甚至匹配失败。

    2.3、计算复杂度高。该方法需要逐像素匹配;又因为上述多种因素的影响,为保证匹配结果的鲁棒性,需要在算法中增加大量的错误剔除策略,因此对算法要求较高,想要实现可靠商用难度大,计算量较大。
    2.4、相机基线限制了测量范围。测量范围和基线(两个摄像头间距)关系很大:基线越大,测量范围越远;基线越小,测量范围越近。所以基线在一定程度上限制了该深度相机的测量范围。


    ---------------项目开源:-----------

    卡内基梅隆大学双目实验室

    Oxford大牛:Andrew Zisserman,http://www.robots.ox.ac.uk/~vgg/hzbook/code/,主要研究多幅图像的几何学,该网站提供了部分工具,相当实用,还有例子

    Cambridge:http://mi.eng.cam.ac.uk/milab.html,剑桥大学的机器智能实验室,里面有三个小组,Computer Vision & Robotics, Machine Intelligence, Speech

    stanford:http://ai.stanford.edu/~asaxena/reconstruction3d/,主要对于单张照片的三维重建

    caltech:http://www.vision.caltech.edu/bouguetj/calib_doc/,这是我们Computer Vision老师课件上的连接,主要是用于摄像机标定的工具集,当然也有涉及对标定图像三维重建的前期处理过程

    JP Tarel:http://perso.lcpc.fr/tarel.jean-philippe/,个人主页


    ------------匹配与3D重建算法:-----------

    https://www.cnblogs.com/polly333/p/5130375.html

    http://blog.csdn.net/wangyaninglm/article/details/51533549

    http://blog.csdn.net/wangyaninglm/article/details/51531333


    https://www.zhihu.com/question/29885222?sort=created

    http://blog.csdn.net/wangyaninglm/article/details/51558656

    http://blog.csdn.net/wangyaninglm/article/details/51558310

    https://www.cnblogs.com/mysunnyday/archive/2011/05/09/2041115.html
     

     

     

     

    参考:

    https://blog.csdn.net/piaoxuezhong/article/details/79016615

    http://m.blog.csdn.net/article/details?id=52829190

    https://blog.csdn.net/a6333230/article/details/82865439

    https://blog.csdn.net/bit_cs2010/article/details/52829190

    展开全文
  • 【双目测距】2 双目测距原理

    千次阅读 2018-11-25 17:05:29
    双目测距原理推导 如下图,为一组平行双目视觉模型。 平行双目立体视觉模型 让两摄像机光心相距T平行放置。 左右成像仪的像素原点都是在图像的左上角; P点为现实场景中的一个目标点; 和是目标点P在左右图像...

    主要看下面的注,相似三角形的求解.

    傻瓜式讲述,没有比这更直白的了。


    双目测距原理推导

    如下图,为一组平行双目视觉模型。

    平行双目立体视觉模型

    让两摄像机光心相距T平行放置。

    左右成像仪的像素原点都是在图像的左上角;

    P点为现实场景中的一个目标点;

    P_{l}P_{r}是目标点P在左右图像上的成像点,在X轴上相应的坐标分别为x_{l}x_{r}

    视差d=x_{l}-x_{r}(双目视差是左右两个相机中的物体在图像中的位置的不同)

    f是焦距(镜头焦距是指镜头光学后主点到焦点的距离,是镜头的重要性能指标。镜头焦距的长短决定了被摄物在成像介质-胶片或CCD等上成像的大小,也就是相当于物和象的比例尺);

    换个角度来看

     

    由△PO_{l}O_{r}相似于△PP_{l}P_{r}得到:

    乍一看,有些小伙伴可能对这个相似三角形有点懵逼,且看下面的注

    注:

    (1)经过标定,主点C_{X}^{left}C_{X}^{right}校准为在左右图像中具有相同的像素坐标。但是注意哦,这不一定是图像的中心点。

    (2)T - (x_{l}-x_{r})为△PP_{l}P_{r}的底边长,如何得到:

    PP_{l}P_{r}底边 = T-C_{X}^{left}P_{l}-P_{r}C_{X}^{right},就是T减去两个颜色不一样的地方。

    由注(1),得(x_{l}-x_{r})就是减去两个颜色不一样的地方。因为C_{X}^{left}C_{X}^{right}这两个点在图像中的位置是一样的,拆分成两个部分;


    视差与深度的关系

    通过以上推导可以发现,深度是与视差成反比的。如下图:

    视差与深度的关系

     

     


    ★finished by songpl, 2018,11,25

    展开全文
  • 学习OpenCV双目测距原理及常见问题解答 转自博客:https://blog.csdn.net/angle_cal/article/details/50800775 一. 整体思路和问题转化. 图1. 双摄像头模型俯视图图1解释了双摄像头测距的原理,书中Z的公式如下:...

    学习OpenCV双目测距原理及常见问题解答

    转自博客:https://blog.csdn.net/angle_cal/article/details/50800775

    一. 整体思路和问题转化.

    这里写图片描述 
    图1. 双摄像头模型俯视图 
    图1解释了双摄像头测距的原理,书中Z的公式如下: 
    这里写图片描述 
    在OpenCV中,f的量纲是像素点,T的量纲由定标棋盘格的实际尺寸和用户输入值确定,一般总是设成毫米,当然为了精度提高也可以设置为0.1毫米量级,d=xl-xr的量纲也是像素点。因此分子分母约去,z的量纲与T相同 
    这里写图片描述 
    图2, 双摄像头模型立体视图 
    图2解释了双摄像头获取空间中某点三维坐标的原理。 
    注意,左镜头光心是世界坐标系的原点,该坐标系是左手屏幕坐标系,所以在该点上方,前方的物体,他的世界坐标中,Y是负数. 
    这里写图片描述 
    可以看到,实际的坐标计算利用的都是相似三角形的原理,其表达式就如同Q矩阵所示。空间中某点的三维坐标就是(X/W, Y/W, Z/W)。所以,得到了Q矩阵,就是得到了一个点的世界坐标. 
    因此,为了精确地求得某个点在三维空间里的距离,我们需要获得的参数有焦距f、视差d、摄像头中心距Tx。如果还需要获得X坐标和Y坐标的话,那么还需要额外知道左右像平面的坐标系与立体坐标系中原点的偏移cx和cy。 
    要测距,就又有这五个参数. 
    f, Tx, cx和cy可以通过立体标定获得初始值,并通过立体校准优化,使得两个摄像头在数学上完全平行放置,并且左右摄像头的cx, cy和f相同(也就是实现下图中左右视图完全平行对准的理想形式)。 
    这里写图片描述 
    立体匹配所做的工作,就是在之前的基础上,求取最后一个变量:视差d(这个d一般需要达到亚像素精度)。从而最终完成求一个点三维坐标所需要的准备工作。

    总结:使用OpenCV进行的立体视觉测距,其实思路是这样的:根据摄像头的成像原理(表现为小孔成像等效模型)和具体设备的成像特性(表现为光心距离,两个焦距,两个镜头安装的相对位置),设法建立像和真实世界的映射关系(表现为上述五个参数),并以摄像机系统为参考系,为真实世界建立绝对坐标系(该坐标系的具体形式请看下文),通过上述映射关系,该方法能够把像点所在的世界坐标位置求解出来,实现距离测量.

    在清楚了上述原理之后,我们也就知道了,所有的这几步:标定、校准和匹配,都是围绕着如何更精确地获得f, d, Tx, cx和cy而设计的。

    二. OpenCV2.4.11的实现.

    按照上述解释,步骤是这样的: 
    1.准备工作:依次完成:标定->校准->匹配这三个操作,获得所需的参数: 
    T_x,f,d, C_x, C_y.其中,标定和校准的目的是求解Q矩阵,匹配的目的是求解视差值d. 
    这里写图片描述 
    2. 通过某种手段,获得待测点在”像世界”中的坐标(x.y),构造向量: 
    这里写图片描述 
    3. 通过Q•W运算,得到世界坐标向量,进而计算距离. 
    4. 具体实现步骤:

    (1)标定和矫正

    函数 findChessboardCorners()以标定盘图片和标定盘参数为输入,得到立体标定的输入参数; 
    函数:stereoCalibrate()输出变量: 
    R – Output rotation matrix (旋转) 
    T – Output translation vector(平移) 
    E – Output essential matrix.(本征) 
    F – Output fundamental matrix.(基础) 
    函数:stereoRectify()的输入变量已经从上面得到,他的输出变量如下: 
    R1 – Output 3x3 rectification transform (rotation matrix) for the first camera. 
    R2 – Output 3x3 rectification transform (rotation matrix) for the second camera. 
    P1 – Output 3x4 projection matrix in the new (rectified) coordinate systems for the first camera. 
    P2 – Output 3x4 projection matrix in the new (rectified) coordinate systems for the second camera. 
    Q – Output disparity-to-depth mapping matrix

    (2)匹配

    OpenCV2.4.11中提供了若干种匹配方法,这里采用的是BM,SGBM,VAR算法,这三个算法在使用的时候都需要构造相应的对象,对其中的输入属性进行设置,利用其提供的”()”操作符的重载执行相关的算法.他们都要求输入左右视图,输出视差图,具体情况如下: 
    SGBM: left – Left 8-bit single-channel or 3-channel image. 
    right – Right image of the same size and the same type as the left one. 
    disp – Output disparity map. It is a 16-bit signed single-channel image of the same size as the input image. It contains disparity values scaled by 16. So, to get the floating-point disparity map, you need to divide each disp element by 16. 
    BM: left – Left 8-bit single-channel image. 
    right – Right image of the same size and the same type as the left one. 
    disparity – Output disparity map. It has the same size as the input images. When disptype==CV_16S, the map is a 16-bit signed single-channel image, containing disparity values scaled by 16. To get the true disparity values from such fixed-point representation, you will need to divide each disp element by 16. If disptype==CV_32F, the disparity map will already contain the real disparity values on output. 
    disptype – Type of the output disparity map, CV_16S (default) or CV_32F. 
    Var: left – Left 8-bit single-channel or 3-channel image. 
    right – Right image of the same size and the same type as the left one. 
    disp – Output disparity map. It is a 8-bit signed single-channel image of the same size as the input image. 
    输出统一以8位视差图计算,不是8位转换成8位.全部采用CV_16S制式.

    (3)取得待测点的图像空间坐标值

    这一步很简单,只需要设法获取图片上的某个点的坐标就可以,此坐标只是相对于图片本身而言,所以可以使用例如鼠标点击或输入坐标的方法

    (4)已经得到了全部的数据,利用Q矩阵进行计算就可以了。

     

    三.代码中的关键函数:

    cvInitUndistortRectifyMap()函数是开源视觉库OpenCV的库函数。该函数是以C语言为基础编写的,而initUndistortRectifyMap()以C++语言为基础编写的。

    函数体

    编辑
    void cvInitUndistortRectifyMap(const CvMat* camera_matrix, const CvMat* dist_coeffs, const CvMat* R, const CvMat* new_camera_matrix, CvArr* mapx, CvArr* mapy)

    参数说明

    编辑
    camera_matrix——输入的3X3的摄像机内参数矩阵
    dist_coeffs——输入的5X1的摄像机畸变系数矩阵
    R——输入的第一和第二相机坐标系之间3X3的旋转矩阵
    new_camera_matrix——输入的校正后的3X3摄像机矩阵(也可用cvStereoRectify()得出的3X4的左或右投影矩阵,其实系统会自动提取该矩阵前三列的有用部分作为输入参数)
    mapx——输出的X坐标重映射参数
    mapy——输出的Y坐标重映射参数
    上述的输入参数可由cvStereoRectify()直接计算得到

    概述

    编辑
    cvInitUndistortRectifyMap()主要用于摄像机校正映射
     
    initUndistortRectifyMap

    函数体

    编辑
    void initUndistortRectifyMap( InputArray cameraMatrix, InputArray distCoeffs,
    InputArray R, InputArray newCameraMatrix,
    Size size, int m1type, OutputArray map1, OutputArray map2 );

    参数解释

    编辑
    cameraMatrix——输入的摄像机内参数矩阵
    distCoeffs——输入的摄像机畸变系数矩阵
    R——输入的第一和第二相机坐标系之间的旋转矩阵
    newCameraMatrix——输入的校正后的3X3摄像机矩阵(也可用cvStereoRectify()得出的3X4的左或右投影矩阵,其实系统会自动提取该矩阵前三列的有用部分作为输入参数)
    size——摄像机采集的无失真图像尺寸
    m1type——map1的数据类型,可以是CV_32FC1或CV_16SC2
    map1——输出的X坐标重映射参数
    map2——输出的Y坐标重映射参数

    概述

    编辑
    initUndistortRectifyMap()主要用于摄像机校正映射

     

    OpenCV三种立体匹配求视差图算法总结:

    首先我们看一下BM算法:

            Ptr<StereoBM> bm = StereoBM::create(16,9);//局部的BM;
            // bm算法
            bm->setROI1(roi1);//左右视图的有效像素区域 在有效视图之外的视差值被消零
            bm->setROI2(roi2);
            bm->setPreFilterType(CV_STEREO_BM_XSOBEL);
            bm->setPreFilterSize(9);//滤波器尺寸 [5,255]奇数
            bm->setPreFilterCap(31);//预处理滤波器的截断值 [1-31] 
            bm->setBlockSize(SADWindowSize > 0 ? SADWindowSize : 15);//sad窗口大小
            bm->setMinDisparity(0);//最小视差值,代表了匹配搜索从哪里开始
            bm->setNumDisparities(numberOfDisparities);//表示最大搜索视差数
            bm->setTextureThreshold(10);//低纹理区域的判断阈值 x方向导数绝对值之和小于阈值
            bm->setUniquenessRatio(15);//视差唯一性百分比  匹配功能函数
            bm->setSpeckleWindowSize(100);//检查视差连通域 变化度的窗口大小
            bm->setSpeckleRange(32);//视差变化阈值  当窗口内视差变化大于阈值时,该窗口内的视差清零
            bm->setDisp12MaxDiff(-1);// 1
    
        该方法速度最快,一副320*240的灰度图匹配时间为31ms 
    

    第二种方法是SGBM方法这是OpenCV的一种新算法:

        Ptr<StereoSGBM> sgbm = StereoSGBM::create(0,16,3);//全局的SGBM;
         // sgbm算法
            sgbm->setPreFilterCap(63);//预处理滤波器的截断值 [1-63] 
            int sgbmWinSize = SADWindowSize > 0 ? SADWindowSize : 3;
            sgbm->setBlockSize(sgbmWinSize);
            int cn = img0.channels();
            sgbm->setP1(8*cn*sgbmWinSize*sgbmWinSize);// 控制视差变化平滑性的参数。P1、P2的值越大,视差越平滑。
        //P1是相邻像素点视差增/减 1 时的惩罚系数;P2是相邻像素点视差变化值大于1时的惩罚系数。P2必须大于P1
            sgbm->setP2(32*cn*sgbmWinSize*sgbmWinSize);
            sgbm->setMinDisparity(0);//最小视差值,代表了匹配搜索从哪里开始
            sgbm->setNumDisparities(numberOfDisparities);//表示最大搜索视差数
            sgbm->setUniquenessRatio(10);//表示匹配功能函数
            sgbm->setSpeckleWindowSize(100);//检查视差连通域 变化度的窗口大小
            sgbm->setSpeckleRange(32);//视差变化阈值  当窗口内视差变化大于阈值时,该窗口内的视差清零
            sgbm->setDisp12MaxDiff(-1);// 1
        //左视图差(直接计算)和右视图差(cvValidateDisparity计算得出)之间的最大允许差异
            if(alg==STEREO_HH)               sgbm->setMode(StereoSGBM::MODE_HH);
            else if(alg==STEREO_SGBM)  sgbm->setMode(StereoSGBM::MODE_SGBM);
            else if(alg==STEREO_3WAY)   sgbm->setMode(StereoSGBM::MODE_SGBM_3WAY);
        各参数设置如BM方法,速度比较快,320*240的灰度图匹配时间为78ms,
    

    第三种为GC方法:

        该方法速度超慢,但效果超好。

     

    四.FAQ:

    Q1:标定时棋盘格的大小如何设定,对最后结果有没有影响?

    A:当然有。在标定时,需要指定一个棋盘方格的长度,这个长度(一般以毫米为单位,如果需要更精确可以设为0.1毫米量级)与实际长度相同,标定得出的结果才能用于实际距离测量。一般如果尺寸设定准确的话,通过立体标定得出的Translation的向量的第一个分量Tx的绝对值就是左右摄像头的中心距。一般可以用这个来验证立体标定的准确度。比如我设定的棋盘格大小为270 (27mm),最终得出的Tx大小就是602.8 (60.28mm),相当精确。

    Q2:通过立体标定得出的Tx符号为什么是负的?

    A:这个其实我也不是很清楚。个人的解释是,立体标定得出的T向量指向是从右摄像头指向左摄像头(也就是Tx为负),而在OpenCV坐标系中,坐标的原点是在左摄像头的。因此,用作校准的时候,要把这个向量的三个分量符号都要换一下,最后求出的距离才会是正的。 
    但是这里还有一个问题,就是Learning OpenCV中Q的表达式,第四行第三列元素是-1/Tx,而在具体实践中,求出来的实际值是1/Tx。这里我和maxwellsdemon讨论下来的结果是,估计书上Q表达式里的这个负号就是为了抵消T向量的反方向所设的,但在实际写OpenCV代码的过程中,那位朋友却没有把这个负号加进去。(一家之言,求更详细的解释)

    Q3:cvFindStereoCorrespondenceBM的视差输出结果单位是?

    A:在OpenCV中,BM函数得出的结果是以16位符号数的形式的存储的,出于精度需要,所有的视差在输出时都扩大了16倍(2^4)。其具体代码表示如下: 
    dptr[y*dstep] = (short)(((ndisp - mind - 1 + mindisp)*256 + (d != 0 ? (p-n)*128/d : 0) + 15) >> 4); 
    可以看到,原始视差在左移8位(256)并且加上一个修正值之后又右移了4位,最终的结果就是左移4位 
    因此,在实际求距离时,cvReprojectTo3D出来的X/W,Y/W,Z/W都要乘以16 (也就是W除以16),才能得到正确的三维坐标信息

    Q4:利用双摄像头进行测距的时候世界坐标的原点究竟在哪里?

    A:世界坐标系的原点是左摄像头凸透镜的光心。 
    说起这个,就不得不提到针孔模型。如图3所示,针孔模型是凸透镜成像的一种简化模型。当物距足够远时(远大于两倍焦距),凸透镜成像可以看作是在焦距处的小孔成像。 
    这里写图片描述 
    在实际计算过程中,为了计算方便,我们将像平面翻转平移到针孔前,从而得到一种数学上更为简单的等价形式(方便相似三角形的计算),如下图所示。 
    这里写图片描述 
    因此,对应图2就可以知道,世界坐标系原点就是左摄像头针孔模型的针孔,也就是左摄像头凸透镜的光心

    Q5:f和d的单位是像素,那这个像素到底表示什么,它与毫米之间又是怎样换算的?

    A:这个问题也与针孔模型相关。在针孔模型中,光线穿过针孔(也就是凸透镜中心)在焦距处上成像,因此,图3的像平面就是摄像头的CCD传感器的表面。每个CCD传感器都有一定的尺寸,也有一定的分辨率,这个就确定了毫米与像素点之间的转换关系。举个例子,CCD的尺寸是8mm X 6mm,分辨率是640X480,那么毫米与像素点之间的转换关系就是80pixel/mm。 
    在实际运用中,我们在数学上将这个像平面等效到小孔前(图4),这样就相当于将在透镜中心点之前假设了一块虚拟的CCD传感器。

    Q6:为什么cvStereoRectify求出的Q矩阵cx, cy, f都与原来的不同?

    A:这个在前文有提到过。在实际测量中,由于摄像头摆放的关系,左右摄像头的f, cx, cy都是不相同的。而为了使左右视图达到完全平行对准的理想形式从而达到数学上运算的方便,立体 校准所做的工作事实上就是在左右像重合区域最大的情况下,让两个摄像头光轴的前向平行,并且让左右摄像头的f, cx, cy相同。因此,Q矩阵中的值与两个instrinsic矩阵的值不一样就可以理解了。

     

     相关网址:

     opencv双目测距实现:https://cloud.tencent.com/developer/article/1082064

    initUndistortRectifyMap:http://www.voidcn.com/article/p-qyftgzxl-brg.html

    真实场景的双目立体匹配(Stereo Matching)获取深度图详解——最终得到深度图像并且填充:https://www.cnblogs.com/riddick/p/8486223.html 

    OpenCV畸变校正原理以及损失有效像素原理分析:https://www.cnblogs.com/riddick/p/6711263.html

    github双目相关理论与实践:https://github.com/melodybinbin/MVision/tree/master/stereo

     

     

    转载于:https://www.cnblogs.com/yuanlibin/p/9460419.html

    展开全文
  • 双目视觉-双目测距原理剖析

    千次阅读 2020-04-08 14:45:29
    这是一篇好文章, 深入浅出,帮助我们更好地了解了双目相机的工作原理。 1.从相似三角形原理可知,我们仅仅需要分析出左眼图片和右眼图片中,相同物体的两个不同坐标,就可以算出深度值。 2. 计算 两个图片之间的...

    这是一篇好文章, 深入浅出,帮助我们更好地了解了双目相机的工作原理。
    1.从相似三角形原理可知,我们仅仅需要分析出左眼图片和右眼图片中,相同物体的两个不同坐标,就可以算出深度值。
    2. 计算 两个图片之间的距离,我们使用优化过的暴力比对法( 只用在一根线上面查找,而不是查找整个图片)
    3. 如果两个相机不平行, 对于左右眼的图片,我们要进行图片变换,变换成水平位置上的图片。 再进行第二步。
    4. 我们比较的时候,不会拿着左边图片上面的一个像素去和右边比较,我们比较的是一个窗口。 通过计算 差值平方均值。算出最小的那个,记为相同点。
    5. 窗口太大,鲁棒性好,但是深度信息不细致。窗口太小,受噪音影响问题大, 误差太大。
    6. 为了克服第五步,我们使用能量优化的图像比对方法。

    深度相机原理揭秘–双目立体视觉

    本文属于转载,见下。

    博文来源:http://www.sohu.com/a/203027140_100007727

    基于双目立体视觉的深度相机类似人类的双眼,和基于TOF、结构光原理的深度相机不同,它不对外主动投射光源,完全依靠拍摄的两张图片(彩色RGB或者灰度图)来计算深度,因此有时候也被称为被动双目深度相机。比较知名的产品有STEROLABS 推出的 ZED 2K Stereo Camera和Point Grey 公司推出的 BumbleBee。

    在这里插入图片描述

    ZED 2K Stereo Camera

    为什么非得用双目相机才能得到深度?

    说到这里,有些读者会问啦:为什么非得用双目相机才能得到深度?我闭上一只眼只用一只眼来观察,也能知道哪个物体离我近哪个离我远啊!是不是说明单目相机也可以获得深度?

    在此解答一下:首先,确实人通过一只眼也可以获得一定的深度信息,不过这背后其实有一些容易忽略的因素在起作用:一是因为人本身对所处的世界是非常了解的(先验知识),因而对日常物品的大小是有一个基本预判的(从小到大多年的视觉训练),根据近大远小的常识确实可以推断出图像中什么离我们远什么离我们近;二是人在单眼观察物体的时候其实人眼是晃动的,相当于一个移动的单目相机,这类似于运动恢复结构(Structure from Motion, SfM)的原理,移动的单目相机通过比较多帧差异确实可以得到深度信息。

    但是实际上,相机毕竟不是人眼,它只会傻傻的按照人的操作拍照,不会学习和思考。下图从物理原理上展示了为什么单目相机不能测量深度值而双目可以的原因。我们看到红色线条上三个不同远近的黑色的点在下方相机上投影在同一个位置,因此单目相机无法分辨成的像到底是远的那个点还是近的那个点,但是它们在上方相机的投影却位于三个不同位置,因此通过两个相机的观察可以确定到底是哪一个点。

    双目相机确定深度示意图

    双目立体视觉深度相机简化流程

    下面简单的总结一下双目立体视觉深度相机的深度测量过程,如下:

    1、首先需要对双目相机进行标定,得到两个相机的内外参数、单应矩阵。

    2、根据标定结果对原始图像校正,校正后的两张图像位于同一平面且互相平行。

    3、对校正后的两张图像进行像素点匹配。

    4、根据匹配结果计算每个像素的深度,从而获得深度图。

    欲知详情,且看下面详细介绍。

    双目立体视觉深度相机详细原理
    在这里插入图片描述

    1

    理想双目相机成像模型

    首先我们从理想的情况开始分析:假设左右两个相机位于同一平面(光轴平行),且相机参数(如焦距f)一致。那么深度值的推导原理和公式如下。公式只涉及到初中学的三角形相似知识,不难看懂。

    理想情况下双目立体视觉相机深度值计算原理

    根据上述推导,空间点P离相机的距离(深度)z=f*b/d,可以发现如果要计算深度z,必须要知道:

    1、相机焦距f,左右相机基线b。这些参数可以通过先验信息或者相机标定得到。

    2、视差d。需要知道左相机的每个像素点(xl, yl)和右相机中对应点(xr, yr)的对应关系。这是双目视觉的核心问题。

    2

    极线约束

    那么问题来了,对于左图中的一个像素点,如何确定该点在右图中的位置?是不是需要我们在整个图像中地毯式搜索一个个匹配?

    答案是:不需要。因为有极线约束(名字听着很吓人)。极线约束对于求解图像对中像素点的对应关系非常重要。

    那什么是极线呢?如下图所示。C1,C2是两个相机,P是空间中的一个点,P和两个相机中心点C1、C2形成了三维空间中的一个平面PC1C2,称为极平面(Epipolar plane)。极平面和两幅图像相交于两条直线,这两条直线称为极线(Epipolar line)。P在相机C1中的成像点是P1,在相机C2中的成像点是P2,但是P的位置事先是未知的。
    在这里插入图片描述
    我们的目标是:对于左图的P1点,寻找它在右图中的对应点P2,这样就能确定P点的空间位置,也就是我们想要的空间物体和相机的距离(深度)。

    所谓极线约束(Epipolar Constraint)就是指当同一个空间点在两幅图像上分别成像时,已知左图投影点p1,那么对应右图投影点p2一定在相对于p1的极线上,这样可以极大的缩小匹配范围。

    根据极线约束的定义,我们可以在下图中直观的看到P2一定在对极线上,所以我们只需要沿着极线搜索一定可以找到和P1的对应点P2。

    极线约束示意图

    细心的朋友会发现上述过程考虑的情况(两相机共面且光轴平行,参数相同)非常理想,相机C1,C2如果不是在同一直线上怎么办?

    事实上,这种情况非常常见,因为有些场景下两个相机需要独立固定,很难保证光心C1,C2完全水平,即使是固定在同一个基板上也会因为装配的原因导致光心不完全水平。如下图所示。我们看到两个相机的极线不仅不平行,还不共面,之前的理想模型那一套推导结果用不了了,这可咋办呢?

    在这里插入图片描述

    非理想情况下的极线

    不急,有办法。我们先来看看这种情况下拍摄的两张左右图片吧,如下所示。左图中三个十字标志的点,在右图中对应的极线是右图中的三条白色直线,也就是对应的搜索区域。我们看到这三条直线并不是水平的,如果进行逐点搜索效率非常低。

    在这里插入图片描述

    左图中三个点(十字标志)在右图中对应的极线是右图中的三条白色直线

    3

    图像矫正技术

    怎么办呢?把不理想情况转化为理想情况不就OK了!这就是图像矫正(Image Rectification)技术。

    图像矫正是通过分别对两张图片用单应(homography)矩阵变换(可以通过标定获得)得到的,的目的就是把两个不同方向的图像平面(下图中灰色平面)重新投影到同一个平面且光轴互相平行(下图中黄色平面),这样就可以用前面理想情况下的模型了,两个相机的极线也变成水平的了。

    图像校正示意图
    在这里插入图片描述
    经过图像矫正后,左图中的像素点只需要沿着水平的极线方向搜索对应点就可以了(开心)。从下图中我们可以看到三个点对应的视差(红色双箭头线段)是不同的,越远的物体视差越小,越近的物体视差越大,这和我们的常识是一致的。

    图像校正后的结果。红色双箭头线段是对应点的视差
    在这里插入图片描述
    上面讲到的对于左图的一个点,沿着它在右图中水平极线方向寻找和它最匹配的像素点,说起来简单,实际操作起来却不容易。这是因为上述都是理想情况下的假设。实际进行像素点匹配的时候会发现几个问题:

    1、实际上要保证两个相机完全共面且参数一致是非常困难的,而且计算过程中也会产生误差累积,因此对于左图的一个点,其在右图的对应点不一定恰好在极线上。但是应该是在极线附近,所以搜索范围需要适当放宽。

    2、单个像素点进行比较鲁棒性很差,很容易受到光照变化和视角不同的影响。

    4

    基于滑动窗口的图像匹配

    上述问题的解决方法:使用滑动窗口来进行匹配。如下图所示。对于左图中的一个像素点(左图中红色方框中心),在右图中从左到右用一个同尺寸滑动窗口内的像素和它计算相似程度,相似度的度量有很多种方法,比如 误差平方和法(Sum of Squared Differences,简称SSD),左右图中两个窗口越相似,SSD越小。下图中下方的SSD曲线显示了计算结果,SSD值最小的位置对应的像素点就是最佳的匹配结果。

    在这里插入图片描述

    滑动窗口匹配原理示意图

    具体操作中还有很多实际问题,比如滑动窗口尺寸。滑动窗口的大小选取还是很有讲究的。下图显示了不同尺寸的滑动窗口对深度图计算结果的影响。从图中我们也不难发现:

    小尺寸的窗口:精度更高、细节更丰富;但是对噪声特别敏感

    大尺寸的窗口:精度不高、细节不够;但是对噪声比较鲁棒

    在这里插入图片描述
    不同尺寸的滑动窗口对深度图计算结果的影响

    虽然基于滑动窗口的匹配方法可以计算得到深度图,但是这种方法匹配效果并不好,而且由于要逐点进行滑动窗口匹配,计算效率也很低。

    5

    基于能量优化的图像匹配

    目前比较主流的方法都是基于能量优化的方法来实现匹配的。能量优化通常会先定义一个能量函数。比如对于两张图中像素点的匹配问题来说,我们定义的能量函数如下图公式1。我们的目的是:

    1、在左图中所有的像素点和右图中对应的像素点越近似越好,反映在图像里就是灰度值越接近越好,也就是下图公式2的描述。

    2、在 同一张图片里,两个相邻的像素点视差(深度值)也应该相近。也就是下图公式3的描述。
    在这里插入图片描述

    能量函数

    上述公式1代表的能量函数就是著名的马尔科夫随机场(Markov Random Field)模型。通过对能量函数最小化,我们最后得到了一个最佳的匹配结果。有了左右图的每个像素的匹配结果,根据前面的深度计算公式就可以得到每个像素点的深度值,最终得到一幅深度图。

    双目立体视觉法优缺点

    根据前面的原理介绍,我们总结一下基于双目立体视觉法深度相机的优缺点。

    1

    优点

    1、对相机硬件要求低,成本也低。因为不需要像TOF和结构光那样使用特殊的发射器和接收器,使用普通的消费级RGB相机即可。

    2、室内外都适用。由于直接根据环境光采集图像,所以在室内、室外都能使用。相比之下,TOF和结构光基本只能在室内使用。

    2

    缺点

    1、对环境光照非常敏感。双目立体视觉法依赖环境中的自然光线采集图像,而由于光照角度变化、光照强度变化等环境因素的影响,拍摄的两张图片亮度差别会比较大,这会对匹配算法提出很大的挑战。如下图是在不同光照条件下拍摄的图片:

    在这里插入图片描述

    不同光照下的图像对比

    另外,在光照较强(会出现过度曝光)和较暗的情况下也会导致算法效果急剧下降。

    2、不适用于单调缺乏纹理的场景。由于双目立体视觉法根据视觉特征进行图像匹配,所以对于缺乏视觉特征的场景(如天空、白墙、沙漠等)会出现匹配困难,导致匹配误差较大甚至匹配失败。

    在这里插入图片描述

    纹理丰富(左)和纹理缺乏场景(右)

    3、计算复杂度高。该方法是纯视觉的方法,需要逐像素计算匹配;又因为上述多种因素的影响,需要保证匹配结果比较鲁棒,所以算法中会增加大量的错误剔除策略,因此对算法要求较高,想要实现可靠商用难度大,计算量较大。

    4、相机基线限制了测量范围。测量范围和基线(两个摄像头间距)关系很大:基线越大,测量范围越远;基线越小,测量范围越近。所以基线在一定程度上限制了该深度相机的测量范围。

    本公众号后续继续推出一系列关于深度相机原理和技术应用文章,敬请关注。

    注:转载请注明来源,违者必究。

    展开全文
  • 我在学习上述两个博客时发现,两者对于双目视觉深度值计算公式的推导过程有些细微的出入。 如图1所示,其中xl与xr,分别为左右相机像平面上的成像点距主点的距离(x方向),可以理解为x1与xr,是在相机坐标系测得的...
  • 双目测距基本原理: 如图,P是待测物体上的某一点,OR与OT分别是两个相机的光心,点P在两个相机感光器上的成像点分别为P和P’(相机的成像平面经过旋转后放在了镜头前方), f为相机焦距,B为两相机中心距,Z...
  • opencv双目测距原理与应用

    千次阅读 2016-12-28 16:38:50
    虽然最近注意力已经不可遏制地被神经科学、大脑记忆机制和各种毕业活动吸引过去了,但是还是觉得有必要把这段时间双目视觉方面的进展总结一下。毕竟从上一篇博文发表之后,很多同仁发E-mail来与我讨论,很多原来的...
  • 学习OpenCV(2)双目测距原理

    千次阅读 2016-03-04 10:39:13
    图1解释了双摄像头测距原理,书中Z的公式如下: 在OpenCV中,f的量纲是像素点,T的量纲由定标棋盘格的实际尺寸和用户输入值确定,一般总是设成毫米,当然为了精度提高也可以设置为0.1毫米量级,d=xl-xr的量纲也...
  • 双目测距数学原理详解

    万次阅读 多人点赞 2016-12-21 11:24:17
    前言最近用到了双目测距的知识,乍想一下这应该是一个很简单很经典的知识了,理论介绍应该很对并且很详尽才对。可是真正想要明白到能给别人讲懂,还是花了一番功夫。网上的类似的文章很多,但是到多都是一样的知识的...
  • 双目测距的原理个人理解 双目摄像机由两个摄像机组成,利用三角测量原理获得场景的深度信息,...双目测距原理: 其中,depth = (f * baseline)/disparity,disparity为视差即xr-xt,baseline为俩相机中心距,f为...
  • 双目视觉测距原理深度剖析:一个被忽略的小问题

    千次阅读 热门讨论 2018-12-21 17:03:22
    这里不对双目视觉测距的原理...对于双目测距原理不了解的,可以参考如下博客,讲解的都很详细: 双目视觉测距原理,数学推导及三维重建资源 双目相机–双目视差与深度距离关系推导详解 以下内容也是由此引发: ...
  • 双目测距原理

    2015-01-21 23:16:00
    http://blog.ifeng.com/article/31086004.html ... 双摄像头测距的OpenCV实现 (有小孔成像模型) OpenCV学习笔记(16)双目测距与三维重建的OpenCV实现问题集锦(一)图像获取与单目定标 OpenCV学习笔记(1...
  • 双目测距基本原理

    2017-11-02 16:06:13
    双目测距基本原理: 如图,P是待测物体上的某一点,OR与OT分别是两个相机的光心,点P在两个相机感光器上的成像点分别为P和P’(相机的成像平面经过旋转后放在了镜头前方),f为相机焦距,B为两相机中心距,Z为我们...
  • opencv双目测距实现

    千次阅读 2017-08-15 15:44:35
    双目测距原理及实现
  • 点击–>双目视觉测距原理 很好的一篇原理入门级文章
  • 双目测距的基本原理

    千次阅读 2016-03-03 16:57:19
    双目测距的基本原理 如上图所示,双目测距主要是利用了目标点在左右两幅视图上成像的横向坐标直接存在的差异(即视差 )与目标点到成像平面的距离Z存在着反比例的关系:Z=fT/d。“@scyscyao :在OpenC
  • 一、双目测距原理 通过对两幅图像视差的计算,直接对前方景物(图像所拍摄到的范围)进行距离测量。双目摄像头的原理与人眼相似。人眼能够感知物体的远近,是由于两只眼睛对同一个物体呈现的图像存在差异,也称...
  • 需求:使用双目摄像头得出物体3D坐标,本质就是利用双目来得到深度信息。 github代码 0 知识扫盲 相机模型 四大坐标关系及其关系 1 相机标定 Q1:用MATLAB标定还是opencv标定? A1:两种我都试了。总结来说,直接...
  • 双目视觉测距原理,数学推导及三维重建资源

    万次阅读 多人点赞 2018-01-09 21:15:20
    先说一下单/双目测距原理区别:单目测距原理:先通过图像匹配进行目标识别(各种车型、行人、物体等),再通过目标在图像中的大小去估算目标距离。这就要求在估算距离之前首先对目标进行准确识别,是汽车还是行人...
  • 提出了一种局部稠密匹配与人工干预相结合的测距方案,利用非特征点与特征点的位置关系,构建“最小矩形”以缩小匹配范围,再应用NCC(归一化互相关)算法对非特征点进行稠密立体匹配,最后根据双目测距原理直接获取...
  • 双目测距相似三角形原理

    千次阅读 2018-03-16 09:57:14
    左边中轴到点P在左相机的成像点也就是xl的距离为 xl 右边中轴到点P在右相机的成像点也就是xr的距离为 -xr 相似三角形得 T-(xl+(-xr)) / Z-f = T / Z
  • 结构光双目视觉测距原理

    千次阅读 2020-02-20 15:04:41
     双目匹配: 先将图像二值化,为了提高边缘误差可以采用正反码图案   搜索策略分为粗匹配和精匹配两个步骤: 粗匹配以像素块为单位,在极线矫正的和结构光对像素块编码标识的基础上,采用一维的...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 169
精华内容 67
关键字:

双目测距原理