精华内容
下载资源
问答
  • 双目相机
    千次阅读
    2019-05-06 14:47:27

     

    双目相机

     

    计算机视觉基础1——视差与深度信息

    目录

    1. 单目
    2. 双目
    3. RGBD
    

    双目立体视觉

    相机标定————畸变矫正————立体校正————极线约束————立体匹配(关键步骤)————三角测量
    

    立体匹配最基本的步骤:

    1)代价计算。
       计算左图一个像素和右图一个像素之间的代价(某种差值)。
       
    2)代价聚合。
       一般基于点之间的匹配很容易受噪声的影响,往往真实匹配的像素的代价并不是最低。
       所以有必要在点的周围建立一个window,让像素块和像素块之间进行比较,这样肯定靠谱些。
       代价聚合往往是局部算法或者半全局算法才会使用,
       全局算法抛弃了window,采用基于全图信息的方式建立能量函数。
       
    3)深度赋值。
       这一步可以区分局部算法与全局算法,局部算法直接优化代价聚合模型。
       而全局算法,要建立一个能量函数,能量函数的数据项往往就是代价聚合公式,例如DoubleBP。
       输出的是一个粗略的视差图。
       
    4)结果优化。
       对上一步得到的粗估计的视差图进行精确计算,策略有很多,
       例如plane fitting,BP,动态规划等。
    

    局部方法

    Winner-takes-All
    赢者通吃————先入为主—————用户黏性
    局部最小
    

    方法有:

    1. Block Matching 块匹配
    
    
    6. CSCA
    

    半全局

    全局

    双目 ros 包 elas

    wiki.ros elas_ros

    github code cyphy-elas-ros

    普通工程 ELAS

    stereo_elas

    双目障碍物检测

    深度学习双目匹配 DispNet

    可以建立 相机坐标系下的 点云

    如需建立 世界坐标系下的点云 需要跟踪 每一帧图像的位姿变化 既需要配合 视觉里程计来使用

    viso2

    机器人视觉 实验室 代码参考 

    机器人视觉 实验室 代码参考 

    elas使用

    节点 Nodes

    节点1. elas_ros Nodes

    完成 双目视差匹配disparity matching, 生成当前相机坐标系下的点云point clouds   camera's local reference frame.

    订阅的话题 Subscribed Topics

    a. <stereo>/left/<image> (sensor_msgs/Image)      左图矫正后的图像 Left rectified stereo image. 
    
    b. <stereo>/right/<image> (sensor_msgs/Image)     右图矫正后的图像 Right rectified stereo image. 
    
    c. <stereo>/left/camera_info (sensor_msgs/CameraInfo) 左相机参数 Camera info for left camera. 
    
    4. <stereo>/right/camera_info (sensor_msgs/CameraInfo) 右相机参数 Camera info for right camera. 
    

    发布的话题 Published Topics

    a. disparity (sensor_msgs/Image)  视差 话题
       Image representing the calculated disparity at each point. 
        Note that the values are scaled to be in the range [0, 255] 
    
    b. point_cloud (sensor_msgs/PointCloud2) 左相机当前坐标系下 的点云地图
        The point cloud assosciated with the calculated disparity in the left camera's local reference frame. 
    
    c. frame_data (elas_ros/ElasFrameData)  结构数据  用于三维重建
        Frame data used for the point cloud concatenation process. See node pc_construction. 
    

    参数 Parameters

    a. ~queue_size (int, default: 5)  队列大小
        Length of the input queues for left and right camera synchronization. 
    
    b. ~approximate_sync (bool, default: false)  同步
        Whether the node should use approximate synchronization of incoming messages. 
        Set to true if cameras do not have synchronised timestamps. 
    

    节点2. pc_construction 三维重建

    This node concatenates the point clouds generated by the elas_ros node.
    

    订阅的话题 Subscribed Topics

    <frame_data> (elas_ros/ElasFrameData)   结构数据  用于三维重建
        The frame data generated by the elas_ros node. 
    
    <pose> (geometry_msgs/PoseStamped)    相机姿态数据  来自视觉里程计
        The pose transformation from base frame to pose frame. 
        This accounts for motion of the camera. This can typically be determined by appropriate visual odometry. 
        See usage notes below. 
    

    发布的话题Published Topics

    point_cloud (sensor_msgs/PointCloud2) 世界坐标系下的点云地图
        The concatenated point cloud. 
    

    参数 Parameters

    ~queue_size (int, default: 5)  队列大小 
        Length of the input queues for frame data and pose synchronization. 
    

      ~approximate_sync (bool, default: false)  同步 Whether the node should use approximate synchronization of incoming messages. Set to true if frame data and pose do not have synchronised timestamps.

    base_frame_id (string)  基坐标系
        The name of the base frame that the concatenated point cloud should be cast into. 
    
    pose_frame_id (string)  相机位姿坐标系
        The name of the frame that the given pose transforms into. 
    

    相机 图像处理流水线 ros包

    image_pipeline

    TablesAreCool
    col 3 isright-aligned$1600
    col 2 iscentered$12
    zebra stripesare neat$1

    显示链接中带括号的图片

    ![][1] [1]: http://latex.codecogs.com/gif.latex?\prod%20(n_{i})+1

    单目 双目相机 实战

    单目标定

    双目标定

    双目匹配

    OpenCV提供了以下四种立体匹配算法的函数:

    1. 基于局部的块匹配    Block Matching(BM) StereoBM
    2. 半全局块匹配        Semi-Global Block Matching(SGBM) StereoSGBM
    >第一步对每一个Pixel使用块匹配BM进行匹配,得到了全部Pixel的disparity map。
    >第二步对Disparity map建立图,用Graph Cut对其进行全局优化。
    >利用Rectification将二维转化为一维
    3. 基于全局的图割      Graph Cut(GC)cvStereoGCState()
    4. 基于全局的 动态规划 Dynamic Programming(DP)cvFindStereoCorrespondence()
    

    双目相机 算法

    ADCensus, SGBM, BM算法参考

    ELAS论文解析

    ELAS代码

    棋盘格

    双目相机 矫正

    * 用法 ./Stereo_Calibr -w=6 -h=8  -s=24.3 stereo_calib.xml   
      我的  ./Stereo_Calibr -w=8 -h=10 -s=200 stereo_calib.xml
    * ./stereo_calib -w=9 -h=6 stereo_calib.xml 标准图像
    *  实际的正方格尺寸在程序中指定 const float squareSize = 2.43f;    
       2.43cm  mm为单位的话为 24.3  0.1mm为精度的话为   243 注意 标定结果单位(纲量)和此一致
    

    原理分析 原理分析2

    径向畸变矫正 光学透镜特效 凸起 k1 k2 k3 三个参数确定

     Xp=Xd(1 + k1*r^2 + k2*r^4 + k3*r^6)
     Yp=Yd(1 + k1*r^2 + k2*r^4 + k3*r^6)
    

    切向畸变矫正 装配误差 p1 p2 两个参数确定

     Xp= Xd + ( 2*p1*y  + p2*(r^2 + 2*x^2) )
     Yp= Yd + ( p1 * (r^2 + 2*y^2) + 2*p2*x )
     r^2 = x^2+y^2
    

    投影公式 世界坐标点 到 相机像素坐标系下

                                                  | Xw|
    *  | u|     |fx  0   ux 0|     |    R   T  |    | Yw|
    *  | v| =   |0   fy  uy 0|  *  |           | *  | Zw| = M*W
    *  | 1|     |0   0  1   0|     |   0 0  0 1|    | 1 |
    

    相机标定和三维重建

    *   像素坐标齐次表示(3*1)  =  内参数矩阵 齐次表示(3*4)  ×  外参数矩阵齐次表示(4*4) ×  物体世界坐标 齐次表示(4*1)
    *   内参数齐次 × 外参数齐次 整合 得到 投影矩阵  3*4    左右两个相机 投影矩阵 P1 = K1*T1   P2 = k2*T2
    *   世界坐标 W  ----> 左相机投影矩阵 P1 ------> 左相机像素点 (u1,v1,1)
    *               ----> 右相机投影矩阵 P2 ------> 右相机像素点 (u2,v2,1)
    

    Q为 视差转深度矩阵 disparity-to-depth mapping matrix

    * Z = f*B/d       =   f    /(d/B)
    * X = Z*(x-c_x)/f = (x-c_x)/(d/B)
    * X = Z*(y-c_y)/f = (y-y_x)/(d/B)
    

    Q为 视差转深度矩阵 参考

    *    Q= | 1   0    0         -c_x     |    Q03
    *       | 0   1    0         -c_y     |    Q13
    *       | 0   0    0          f       |    Q23
    *       | 0   0   -1/B   (c_x-c_x')/B |    c_x和c_x' 为左右相机 平面坐标中心的差值(内参数)
    *                   Q32        Q33
    
    *  以左相机光心为世界坐标系原点   左手坐标系Z  垂直向后指向 相机平面  
    *           |x|      | x-c_x           |     |X|
    *           |y|      | y-c_y           |     |Y|
    *   Q    *  |d| =    |   f             |  =  |Z|======>  Z'  =   Z/W =     f/((-d+c_x-c_x')/B)
    *           |1|      |(-d+c_x-c_x')/B  |     |W|         X'  =   X/W = ( x-c_x)/((-d+c_x-c_x')/B)
                                                             Y'  =   Y/W = ( y-c_y)/((-d+c_x-c_x')/B)
                                                            与实际值相差一个负号
    

    双目 视差与深度的关系

    Z = f * T / D   
    f 焦距 量纲为像素点  
    T 左右相机基线长度 
    量纲和标定时 所给标定板尺寸 相同 
    D视差 量纲也为 像素点 分子分母约去,
    Z的量纲同 T
    

    像素单位与 实际物理尺寸的关系

    * CCD的尺寸是8mm X 6mm,帧画面的分辨率设置为640X480,那么毫米与像素点之间的转换关系就是80pixel/mm
    * CCD传感器每个像素点的物理大小为dx*dy,相应地,就有 dx=dy=1/80
    * 假设像素点的大小为k x l,其中 fx = f / k, fy = f / (l * sinA), 
      A一般假设为 90°,是指摄像头坐标系的偏斜度(就是镜头坐标和CCD是否垂直)。
    * 摄像头矩阵(内参)的目的是把图像的点从图像坐标转换成实际物理的三维坐标。因此其中的fx,y, cx, cy 都是使用类似上面的纲量。
    * 同样,Q 中的变量 f,cx, cy 也应该是一样的。
    
        参考代码 
        https://github.com/yuhuazou/StereoVision/blob/master/StereoVision/StereoMatch.cpp
        https://blog.csdn.net/hujingshuang/article/details/47759579
    
        http://blog.sina.com.cn/s/blog_c3db2f830101fp2l.html
    

    视差快匹配代价函数:

     【1】对应像素差的绝对值和(SAD, Sum of Absolute Differences) 
    
     【2】对应像素差的平方和(SSD, Sum of Squared Differences)
    
     【3】图像的相关性(NCC, Normalized Cross Correlation) 归一化积相关算法
    
     【4】ADCensus 代价

     

     

    ==============================================

    双目匹配

    手工设计的特征   匹配代价  

    1. 像素差的绝对值(SAD, Sum of Absolute Differences) 
    2. 像素差的平方和(SSD, Sum of Squared Differences)
    3. 图像的相关性(NCC, Normalized Cross Correlation) 
    4. Census 局部空间结构 汉明距离 匹配代价 
    5. AD + Census
    6. SD + Census
    7. ...
    

    卷积网络学习的特征 匹配代价

    Stereo Matching by Training a Convolutional Neural Network to Compare Image Patches 
    

    卷积网络双目匹配

    输入:两个图像块
    输出:匹配代价 Match Cost
    

    Network I

    two img --->two CNN ----> 连接(concatenate)----> 全连接 ----->相似性得分(similarity score)
    
    Small patch size 
    “Big” network(~600K) 
    Binary prediction
    

    Network II

    two img --->two CNN ---->标准化(normalizer)----->点乘(dot product) ----->相似性得分(similarity score)
    
    Dot-product 
    Small network
    Hinge loss
    

    Network III

    two img --->two CNN(共享权重)---------->相关性----->
    Full content 
    Dot-product 
    Larger patch 
    Log loss
    

    Dataset 数据集 Stereo Datasets

    middlebury数据集

    Middlebury 数据集

    KITTI Vision Benchmark Suite数据集

    KITTI 数据集

    训练

    1. 预处理,数据增强  Preprocessing, data-augmentation
    2. 网络:  梯度聚合  network: gradient aggregated 
    3. SGD;  Batch Normalization 批量化 
    

    Refinement in practice Smoothing 平滑

    代价聚合  Cost-aggregation 
        1.平均邻近位置 Averaging neighboring locations
        2.奇特的“邻居” 外点(遮挡点+不稳定)
    全局能量函数
    SGM(Stereo Processing by Semi-Global Matching and Mutual Information) 
    
    CRF  
    dynamic programming
    
    Border fixing(CNN) 
    Left-right consistency 
    Further smooth 
    Outlier detector
    

    三角测量

    深度与视差成反比 Depth is inversely proportional to disparity

    Z = fB/d 
      z:深度
      f:相机焦距
      d:像素点视差
    Y = (u - cy)*Z/f
    X = (v - cx)*Z/f
    更多相关内容
  • 一些双目相机的总结比较(realsense,mynteye,zedmini)Realsense D435ZED MINI小觅 Mynt Eye D系列 Realsense D435 Realsense是我最早使用的双目深度相机,我认为realsense最大的优点就是它是市面上各种功能最齐全...
  • c++程序,vs2017上运行,可以由双目相机拍得的照片任意一点求取该点的三维坐标,误差在1%左右。
  • matlab工具箱,可完成单目相机的标定、双目相机的标定,调用方便。
  • 双目相机三维重建

    2019-04-09 10:29:56
    matlab实现双目标定,畸变矫正和立体校正,再用vs实现三维重建,亲测可用。
  • 双目相机驱动安装说明,系统安装杀毒软件或者防火墙时,安装驱动会弹出阻止或者允许往计算机系统文件夹、注册表下copy或者注册文件。此时请选择“允许”,否则设备可能无法正常运行。1. USB支持USB接口的相机包括...
  • 现有双目相机标定的方法是通过矩阵变换求得各个相机间的旋转平移关系,再通过优化求得最终参数。非线性优化步骤多,相机内外参数与镜头畸变存在耦合,时间花费较大。提出一种畸变矫正与平面单应性矩阵结合的双目相机...
  • 标定板拍摄的张数要能覆盖整个测量空间及整个测量视场,把相机图像分成四个象限(如图1所示),应保证拍摄的标定板图像均匀分布在四个象限中,且在每个象限中建议进行不同方向的两次倾斜,图2是一组推荐摆放方式图片...
  • 本程序为C++程序,运行环境为vs2017,可使用。工程文件位于文件夹sCam_Demo。
  • 针对高速摄像条件下双目同步立体匹配存在困难的问题,提出了一种基于双目相机的空间直线运动轨迹快速测量算法。在建立了摄像机空间坐标系的基础上,基于小孔成像原理以及目标点与对应点的映射关系,构建了成像模型。...
  • 基于opencv的双目相机标定代码

    热门讨论 2015-11-23 17:34:26
    双目标定代码。解决方案Opencv已配置好。里面有说明文档和实验图片。可以直接运行,也可以根据自己的需要重新拍摄图像进行双目标定。
  • matlab双目标定步骤介绍
  • 双目相机的标定程序,值得参考。里面还有标定的参考图片
  • 双目相机驱动

    2018-08-06 09:31:16
    双目相机驱动用于驱动双目相机,此程序经实践好使,稳定运行
  • 双目相机采集找票

    2017-08-05 13:32:13
    软件上对双目相机进行图像采集,主要用在相机标定的图像采集过程中
  • 将标定相机的参数导出Excel文件和TXT两种格式的程序:
  • 双目相机标定代码

    2018-06-14 15:26:28
    该资源主要是针对双目相机标定,可以进行计算机视觉的下一步工作
  • Matlab双目相机标定

    千次阅读 热门讨论 2022-04-01 14:50:06
    现在有许多双目相机在出厂时就已经标定好了,用户拿到手后可以直接使用,例如Intel Realsense系列。但是有些相机出厂的时候并没有完成标定工作,因而这个时候就需要我们自己来标定。由于笔者曾改装过一个双目相机,...

    1 概述

    现在有许多双目相机在出厂时就已经标定好了,用户拿到手后可以直接使用,例如Intel Realsense系列。但是有些相机出厂的时候并没有完成标定工作,因而这个时候就需要我们自己来标定。由于笔者曾改装过一个双目相机,最远可以测至50m,因此有一些心得体会想给大家分享一下。本文主要介绍双目相机标定的整个过程,以及导出标定数据的方法。

    相机标定主要分为手动标定和自动标定,手动标定比较繁琐,这里主要介绍基于matlab工具箱的自动标定方式来对双目相机进行标定。具体的相关标定细节也可以参照这篇博客:matlab双目标定(详细过程),里面有详细介绍。

    2 Matlab工具箱标定

    首先需要准备一张棋盘,如下图所示。对于标定不同测距范围相机所用的棋盘方格宽度会有所不同。对于短焦双目相机(测距范围在20m以内),棋盘中方格的宽度达到20mm即可;对于长焦双目相机(测距范围在40m左右),棋盘中方格的宽度需要尽量大,否则会影响标定的精度,一般至少达到60mm。

    笔者在标定长焦相机时方格长宽选择60mm。然后运行项目文件中photo.py脚本文件对棋盘进行多角度拍摄,每按下一次s键,会保存一组左右镜头的照片,照片保存的路径参数可以由用户自由设定,参数名为folder。

    # !/usr/bin/python
    # -*- coding: utf-8 -*-
    import cv2
    import time
    
    AUTO = False  # 自动拍照,或手动按s键拍照
    INTERVAL = 2  # 自动拍照间隔
    
    cap = cv2.VideoCapture(0 + cv2.CAP_DSHOW)  # windows下开启摄像头是采用如下语句(微软特有):cv2.VideoCapture( camera_number + cv2.CAP_DSHOW)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 2560)  # 设置双目的宽度
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)  # 设置双目的高度
    
    # 显示缓存数
    # print(cap.get(cv2.CAP_PROP_BUFFERSIZE))
    # 设置缓存区的大小
    # cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
    
    print(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    print(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    
    #设置FPS
    # print('setfps', cap.set(cv2.CAP_PROP_FPS, 25))
    # print(cap.get(cv2.CAP_PROP_FPS))
    
    counter = 0
    utc = time.time()
    folder = "images/"  # 拍照文件目录
    
    
    def shot(pos, frame):
        global counter
        path = folder + pos + "_" + str(counter) + ".jpg"
        cv2.imwrite(path, frame)
        print("snapshot saved into: " + path)
    
    
    while True:
        ret, frame = cap.read()
    
        if not ret:
            print("camera is not connected!")
            break
    
        left_frame = frame[0:720, 0:1280]
        right_frame = frame[0:720, 1280:2560]
    
        cv2.imshow("left", left_frame)
        cv2.imshow("right", right_frame)
    
        now = time.time()
        if AUTO and now - utc >= INTERVAL:
            shot("left", left_frame)
            shot("right", right_frame)
            counter += 1
            utc = now
    
        key = cv2.waitKey(1)
        if key == ord("q"):
            break
        elif key & 0xFF == ord("s"):
            shot("left", left_frame)
            shot("right", right_frame)
            counter += 1
    
    cap.release()

    注意尽量拍摄多组照片,这样可以提高标定效果,标定效果的好坏直接影响到测距的精度。对于短焦相机通常拍摄40组照片即可;长焦相机通常会需要更多组照片,笔者在标定长焦相机时拍摄了60组。

    照片拍摄好后,进入matlab标定工具箱,如下图所示。注意:不要选择matlab2020b版本,笔者测试过该版本无法正常使用标定工具箱,可以使用matlab2020a版本。

     其中Stero Camera Cailbrator为双目标定工具箱,Camera Cailbrator为单目相机标定工具箱,因此这里选择Stero Camera Cailbrator工具箱。进入工具箱以后,选择Add Images。然后选择左右相机照片的路径,Size of checkerboard square为棋盘中每一个方格的长度,单位为毫米,一定要准确测量方格的长度,如下图所示。

    点击确定以后,Radial Distortion Compute选择3 Coefficients和Tangential Distortion,然后点击Calibrate进行校准。不过校准前需要剔除一些原点不一致的点,保证所有照片的原点一致。校准过程中可以可以Reprojection Errors曲线,降低误差,如下图所示。 

    3 导出标定数据 

    标定好后将标定数据导入到工作空间,点击Export Camera Parameters即可。此时我们已经拿到标定数据了,为了避免手工获取数据时出错,笔者写了一个脚本可以直接获取标定数据,并保存到表格文件中,之后直接复制粘贴即可。

    rowName = cell(1,10);
    rowName{1,1} = '平移矩阵';
    rowName{1,2} = '旋转矩阵';
    rowName{1,3} = '相机1内参矩阵';
    rowName{1,4} = '相机1径向畸变';
    rowName{1,5} = '相机1切向畸变';
    rowName{1,6} = '相机2内参矩阵';
    rowName{1,7} = '相机2径向畸变';
    rowName{1,8} = '相机2切向畸变';
    rowName{1,9} = '相机1畸变向量';
    rowName{1,10} = '相机2畸变向量';
    xlswrite('out.xlsx',rowName(1,1),1,'A1');
    xlswrite('out.xlsx',rowName(1,2),1,'A2');
    xlswrite('out.xlsx',rowName(1,3),1,'A5');
    xlswrite('out.xlsx',rowName(1,4),1,'A8');
    xlswrite('out.xlsx',rowName(1,5),1,'A9');
    xlswrite('out.xlsx',rowName(1,6),1,'A10');
    xlswrite('out.xlsx',rowName(1,7),1,'A13');
    xlswrite('out.xlsx',rowName(1,8),1,'A14');
    xlswrite('out.xlsx',rowName(1,9),1,'A15');
    xlswrite('out.xlsx',rowName(1,10),1,'A16');
    xlswrite('out.xlsx',stereoParams.TranslationOfCamera2,1,'B1');  % 平移矩阵
    xlswrite('out.xlsx',stereoParams.RotationOfCamera2.',1,'B2');  % 旋转矩阵
    xlswrite('out.xlsx',stereoParams.CameraParameters1.IntrinsicMatrix.',1,'B5');  % 相机1内参矩阵
    xlswrite('out.xlsx',stereoParams.CameraParameters1.RadialDistortion,1,'B8');  % 相机1径向畸变(1,2,5)
    xlswrite('out.xlsx',stereoParams.CameraParameters1.TangentialDistortion,1,'B9');  % 相机1切向畸变(3,4)
    xlswrite('out.xlsx',stereoParams.CameraParameters2.IntrinsicMatrix.',1,'B10');  % 相机2内参矩阵
    xlswrite('out.xlsx',stereoParams.CameraParameters2.RadialDistortion,1,'B13');  % 相机2径向畸变(1,2,5)
    xlswrite('out.xlsx',stereoParams.CameraParameters2.TangentialDistortion,1,'B14');  % 相机2切向畸变(3,4)
    xlswrite('out.xlsx',[stereoParams.CameraParameters1.RadialDistortion(1:2), stereoParams.CameraParameters1.TangentialDistortion,...
        stereoParams.CameraParameters1.RadialDistortion(3)],1,'B15');  % 相机1畸变向量
    xlswrite('out.xlsx',[stereoParams.CameraParameters2.RadialDistortion(1:2), stereoParams.CameraParameters2.TangentialDistortion,...
        stereoParams.CameraParameters2.RadialDistortion(3)],1,'B16');  % 相机2畸变向量

    标定数据文件保存的路径即为当前程序的路径,要想保存到其他路径直接修改脚本中的路径即可,导出的参数如下图所示。

    将表格中的数据复制到双目相机配置文件中,其中相机1内参复制到left_camera_matrix中,相机1畸变复制到left_distortion中,相机2内参复制到right_camera_matrix中,相机2畸变复制到right_distortion中,旋转矩阵复制到R中,转移矩阵复制到T中,如下图所示。

    至此,双目标定部分就已经完成。注意:标定时照片的尺寸与测距时照片的尺寸一定要保持一致 

    展开全文
  • 输入左右相机采集的一系列图像(包括目标和标定板),实现相机内外参数标定。并利用立体视觉原理计算目标相对左右相机的**空间三维坐标以及空间距离**。 圆点靶标相对于棋盘格靶标来说,具有一定的局限性,同时又有...
  • 双目相机标定

    热门讨论 2012-05-24 10:50:17
    张正友标定法基于opencv源代码 编译通过 没有问题 还有自己拍的待标定图片 可以直接使用
  • 双目相机stereo-vision

    千次阅读 2022-03-25 14:31:08
    双目立体视觉深度相机测距流程:(1)需要对双目相机进行相机标定,得到两个相机的内外参数、单应矩阵。 (2) 根据标定结果对原始图像进行图像校正,校正后的两张图像位于同一平面且互相平行。 (3)双目匹配,对校正后...

    在这里插入图片描述

    为什么单目摄像机不能测深度?

    我们看到红色线条上三个不同远近的黑色的点在下方相机上投影在同一个位置,因此单目相机无法分辨成的像到底是远的那个还是近的那个。

    双目立体视觉深度相机测距流程:
    (1)需要对双目相机进行相机标定,得到两个相机的内外参数、单应矩阵。
    (2) 根据标定结果对原始图像进行图像校正,校正后的两张图像位于同一平面且互相平行。
    (3)双目匹配,对校正后的两张图像进行像素点匹配
    (4)根据匹配结果计算每个像素的深度,从而获得深度图

    理想的双目相机模型:

     可求得深度值Z为:

    Z=f\frac{B}{d}=f\frac{B}{_{Xr}-_{Xt}}

    B:双目相机之间的距离,称为基线。

    f:双目相机的焦距(该焦距要转换为以像素为单位的焦距)。

    d:称为视差,即物体在左右相机中成像的点距成像平面边缘的距离(成像点的在图像平面上的像素坐标的行像素)。

    假设目标点在左视图中的坐标为(x,y)--为像素坐标系下的坐标值,在左右视图上形成的视差为d,

    目标点在以左摄像头光心为原点的世界坐标系中的坐标为(X,Y,Z),则存在所示的变换矩阵Q,使

    '

    上式中的负号,是因为T_{x}为两台相机投影中心间的平移值,定义为复值,所以添加负号。

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

    图像标定:

    选择张氏标定法对相机进行标定获取相机内外参数

    单目相机,或者双目相机的标定可以直接通过matlab中的相机标定模块。

    图像立体校正:

    极限约束: 

    什么是极线呢?如下图所示,两个相机,p是空间中一点,P和两个相机中心点形成了三维空间中的一个平面,称为极平面极平面和两幅图像相交于两条直线,这两条直线为极线。p在相机C1中的成像点是P1,在相机C2中的成像点是P2,但p的位置事先是未知的。
    我们的目标是:对于左图中的P1点,寻找它在右图中的对应点P2,这样就可以获取视差d。这样就能确定P点的空间位置,也就是我们想要的空间物体和相机的距离。

    首先要把该点在左右视图上两个对应的像点匹配起来。

    然而,在二维空间上匹配对应点是非常耗时的,为了减少匹配搜索范围,我们可以利用极线约束使得对应点的匹配由二维搜索降为一维搜索。

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

    非理想双目相机成像模型
    有些场景下两个相机,很难保证光心C1、C2完全水平,即使是固定在同一基板上也会因为装配的原因导致光心不水平,如上图所示。

     

    把不理想的转化为理想情况,这就是图像矫正技术。
    图像立体校正技术:就是要把消除畸变后的两幅图像严格地行对应,使得两幅图像的对极线恰好在同一水平线上,这样一幅图像上任意一点与其在另一幅图像上的对应点就必然具有相同的行号,只需在该行进行一维搜索即可匹配到对应点。

           可采用OpenCV中自有的函数stereoCalibrate() ,stereoRectify() ,initUndistort RectifyMap() 等进行图像校正。

    函数stereoCalibrate() 作用是获取左右相机的内外参数,且求出左右两个相机的相对位置关系;

    函数stereoRectify() 作用是计算左右相机进行图像矫正所需要的映射矩阵;

    函数initUndistort RectifyMap() 函数用于计算无畸变和修正的转换关系。

    图像立体匹配:

            立体匹配是寻找同一个目标在左相机上的成像点和右相机的成像点,进而求出左,右图像中的视差值的算法。

            可采用OpenCV中的自有函数BM(),SGBM()等其它函数实现立体匹配。

            对于左图的一个像素点点,沿着它在右图中水平极线方向寻找和它最匹配的像素点,说起来简单,实际操作起来却不容易。这是因为上述都是理想情况下的假设。实际进行像素点匹配的时候会发现几个问题:

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

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

           

            基于滑动窗口的图像匹配:

    上述问题的解决方法:

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

    具体操作中还有很多实际问题,比如滑动窗口尺寸。滑动窗口的大小选取还是很有讲究的。

    小尺寸的窗口:精度更高、细节更丰富;但是对噪声特别敏感。大尺寸的窗口:精度不高、细节不够;但是对噪声比较鲁棒

    由于要逐点进行滑动窗口匹配,计算效率也很低。

            基于能量优化的图像匹配

    目前比较主流的方法都是基于能量优化的方法来实现匹配的。能量优化通常会先定义一个能量函数。

    影响因素:

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

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

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

    视差求精:

            为了提高最终视差图的质量,往往通过视差求精来对视差图进行进一步处理,在保证物体内部视差较为平滑而又能较好地保持物体的边缘的情况下去除奇异数据的影响。

            常见的求精方法包括左右一致性检测(Left-Right Consistency(LRC) check)、视差图滤波和连通区域检测,孔洞填充。

            经过立体匹配求解的视差结果是一个离散的整数序列,这与真实世界中情况是不相符的,所以往往通过亚像素插值来进一步使视差结果精细化,常用插值法来进行视差值求精。

    左右一致性检测:

    有些点可能只在双目相机中其一的相机可以看到,但对于另一相机看不到的点。在立体匹配算法中如果不针对遮挡区域做一些特殊处理是不可能通过单幅图提供的有限信息得到遮挡点的正确视差的。遮挡点通常是一块连续的区域,记作occluded region/area。

    左右一致性检测作用是实现遮挡检测(Occlusion Detection),得到左图对应的遮挡图像,以实现对遮挡点的视差的计算。

    根据左右两幅输入图像,分别得到左右两幅视差图。对于左图中的一个点p,求得的视差值是d1,那么p在右图里的对应点应该是(p-d1),(p-d1)的视差值记作d2。若|d1-d2|>threshold(一般为1个像素),p标记为遮挡点(occluded point)。

    得到了二值的遮挡图像,之后是为所有的遮挡点赋予合理的视差值。对于左图而言,遮挡点一般存在于背景区域和前景区域接触的地方。遮挡的产生正是因为前景比背景的偏移量更大,从而将背景遮盖。
    具体赋值方法是:对于一个遮挡点p,分别水平往左和往右找到第一个非遮挡点,记作pl、pr。点p的视差值赋成pl和pr两者中视差值中较小的那一个。d(p)= min (d(pl),d(pr))。
     

    视差图滤波:滤波去躁主要用于去除视差图中由于误匹配造成的孤立噪点,视差图后处理中常用的两种滤波方法有中值滤波和双边滤波

    中值滤波是一种典型的非线性滤波技术,其基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值,该方法在去除脉冲噪声、椒盐噪声的同时又能保留图像的边缘细节。

    双边滤波是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。

    亚像素:

    像素是成像面的基本单位也是最小单位,通常被称为图像的物理分辨率。

    如130万像素为1280*1024;如果成像系统要显示的对象尺寸小于物理分辨率时,成像系统是无法正常辨识出来的。

    实际上,“亚像素”应该是存在的,只是硬件上没有比像素更细微的传感器把它检测出来而已,于是在软件上通过亚像素细分算法对物理分辨率的近似优化结果。

    例如:某CMOS成像芯片,其像素间距为4.5um。在成像时,对物理世界中连续的图像进行了离散化处理,这时成像面上每一个像素点只代表其附近的颜色。

    而两个像素之间有4.5um的距离,在宏观上可以看作是连在一起的,但在微观上它们之间还有无限更小的东西存在,是两个物理像素之间的“像素”,这些更小的东西就称为“亚像素”。

            亚像素精度是指相邻两像素之间细分情况输入值通常为二分之一,三分之一或四分之一。这意味着每个像素将被分为更小的单元从而对这些更小的单元实施插值算法。例如,如果选择四分之一,就相当于每个像素在横向和纵向上都被当作四个像素来计算。也就是上面图里的红色点之间有三个黑色点。这样通过亚像素插值的方法可以实现从小矩形到大矩形的映射,从而提高分辨率。

    展开全文
  • 双目相机标定(三)

    千次阅读 2021-10-29 11:57:52
    双目相机标定目的:求出左、右相机的内、外参数矩阵以及畸变参数 使用软件:matlab 2016 标定过程分两步走: 图像采集 matlab工具箱标定 二、图像采集 本实例采用的双目相机如下图所示: 将双目相机打开,同时采集...

    一、标定流程
    双目相机标定目的:求出左、右相机的内、外参数矩阵以及畸变参数
    使用软件:matlab 2016

    标定过程分两步走:

    图像采集
    matlab工具箱标定

    二、图像采集
    本实例采用的双目相机如下图所示:
    在这里插入图片描述
    将双目相机打开,同时采集左右相机图像
    在这里插入图片描述

    点击Capture,即可抓拍。为了保证标定效果,笔者建议将标定棋盘放在不同位置,抓拍十张以上照片。左相机拍摄图像分别命名为01_l,…,15_l, 右相机拍摄图像分别命名为01_r,…,15_r。

    三、MATLAB标定
    打开matlab,在命令行窗口输入stereoCameraCalibrator,运行。
    在这里插入图片描述
    点击界面左上角的Add Images,输入左相机图片和右相机图片所在的文件夹,以及标定板的网格尺寸。(本人使用的标定板尺寸为30mm),Camera1代表左摄像头,Camera2代表右摄像头,分别选择存放着左右图像的文件夹,需要特别注意的是棋盘格的边长应该根据打印的实际大小填写,单位可以选择,然后点击OK,程序会自动检测采集的图像到底有多少可以使用,可以说MATLAB2015的这个工具十分挑剔,如果角度不好的话,将使用不了,因此在采集图像时,最好多的采集一些。
    在这里插入图片描述
    点击确定,标定板上的点就会被自动识别。
    在这里插入图片描述

    在这里插入图片描述

    点击界面上方的Calibrate键,启动标定过程。在界面下方可以看到误差统计和可视化展示。
    在这里插入图片描述
    左下方的直方图为左右图像的标定误差,点击误差较大的直方图,可以直接在左边的图像对中找到对应的图像,右键选择“Remove and Recalibrate”,可以重复上述步骤,直到认为误差满足标定需求为止。
    在这里插入图片描述

    点击界面上方按钮Export Camera Parameters,即可导出标定结果。在matlab主界面可查看。
    在这里插入图片描述

    左右相机的内参数矩阵、畸变参数以及旋转矩阵、平移矩阵都可以得出。
    TranslationOfCamera2:相机2相对于相机1的偏移矩阵,可以直接使用。
    RotationOfCamera2:相机2相对于相机1的旋转矩阵,需要转置之后才能使用。

    CameraParameters1与CameraParameters2为左右摄像头的单独标定参数。

    IntrinsicMatrix存放的是摄像头的内参,只与摄像机的内部结构有关,需要先转置再使用。
    RadialDistortion:径向畸变,摄像头由于光学透镜的特性使得成像存在着径向畸变,可由K1,K2,K3确定。
    TangentialDistortion:切向畸变,由于装配方面的误差,传感器与光学镜头之间并非完全平行,因此成像存在切向畸变,可由两个参数P1,P2确定。
    使用时,需要注意参数的排放顺序,即K1,K2,P1,P2,K3。切记不可弄错,否则后续的立体匹配会出现很大的偏差。

    1内参:
    在这里插入图片描述
    2194.0374 0 1085
    0 3549.8842 -2491.2731
    0 0 1

    相机2内参
    在这里插入图片描述
    260.9973 0 426.0523
    0 265.7492 377.6565
    0 0 1

    相机1畸变系数
    相机2畸变系数

    旋转矩阵
    0.982202495730308 0.0864911805250721 0.166725922017345
    -0.178953161969313 0.161336812150683 0.970539127941908
    0.0570440461603078 -0.983102084595712 0.173943289784993

    平移矩阵
    258.557506370963 264.451009975917 -454.967875210028

    第二次试验
    平移矩阵
    -23.3584685492320 -98.9499465703022 -257.155176711110

    旋转矩阵:
    原始数据:
    0.998544372591077 0.0111484632752088 0.0527716565335433
    -0.00998411204137380 0.999701995537482 -0.0222763916539695
    -0.0530042778786603 0.0217170873962663 0.998358109418452
    转置数据
    0.9985 -0.0099 -0.0530
    0.0111 0.9997 0.0217
    0.0527 -0.0222 0.9983

    相机1内参
    原始数据

    4113.85440617487 0 0
    11.8952154910051 4127.58781534608 0
    274.491190908276 712.869235806806 1

    3268.47251 0 639.5
    0 3268.47251 479.5
    0 0 1

    相机2内参:
    3268.47251 0 639.5
    0 3268.47251 479.5
    0 0 1

    标定结果的验证:
    在这里插入图片描述
    双目相机获取深度原理

    双目相机一般由左眼和右眼两个水平放置的相机组成。当然也可以做成上下两个目,但我们见到的主流双目都是做成左右的。在左右双目的相机中,我们可以把两个相机都看作针孔相机。它们是水平放置的,意味两个相机的光圈中心都位于x轴上。它们的距离称为双目相机的基线(Baseline,记作b),是双目的重要参数。双目相机一般由左眼和右眼两个水平放置的相机组成。当然也可以做成上下两个目,但我们见到的主流双目都是做成左右的。在左右双目的相机中,我们可以把两个相机都看作针孔相机。它们是水平放置的,意味两个相机的光圈中心都位于x轴上。它们的距离称为双目相机的基线(Baseline,记作b),是双目的重要参数。

    在这里插入图片描述

    图1双目相机的成像模型。OL,OR为左右光圈中心,蓝色框为成像平面,f为焦距。uL和uR为成像平面的坐标。请注意按照图中坐标定义,uR应该是负数,所以图中标出的距离为uR。
    现在,考虑一个空间点P,它在左眼和右眼各成一像,记作PL,PR。由于相机基线的存在,这两个成像位置是不同的。理想情况下,由于左右相机只有在x轴上有位移,因此 P的像也只在x轴(对应图像的u轴)上有差异。我们记它在左侧的坐标为uL,右侧坐标为uR。那么,它们的几何关系如图1右侧所示。根据三角形P−PL−PR和P−OL−OR 的相似关系,有:
    在这里插入图片描述(1.1)
    稍加整理,得:
    在这里插入图片描述(1.2)
    这里d为左右图的横坐标之差,称为视差(Disparity)。根据视差,我们可以估计一个像素离相机的距离。视差与距离成反比:视差越大,距离越近。同时,由于视差最小为一个像素,于是双目的深度存在一个理论上的最大值,由fb确定。我们看到,当基线越长时,双目最大能测到的距离就会变远;反之,小型双目器件则只能测量很近的距离。

    虽然由视差计算深度的公式很简洁,但视差d本身的计算却比较困难。我们需要确切地知道左眼图像某个像素出现在右眼图像的哪一个位置(即对应关系),这件事亦属于“人类觉得容易而计算机觉得困难”的事务。当我们想计算每个像素的深度时,其计算量与精度都将成为问题,而且只有在图像纹理变化丰富的地方才能计算视差。由于计算量的原因,双目深度估计仍需要使用GPU或FPGA来计算。

    双目图像标定后矫正解析
    在双目视觉中,我们对相机进行标定和校正,最终目的是使得两个相机的光轴完全平行,这样才能够继续后续的深度计算,三维重建。这样的校正在OPencv中采用的是Bouguet的极线校正的算法。

    校正前的左右相机的光心并不是平行的,两个光心的连线就叫基线(主镜头中心的连线),像平面与基线的交点就是极点,像点与极点所在的直线就是极线,左右极线与基线构成的平面就是空间点对应的极平面。

    校正后,极点在无穷远处,两个相机的光轴平行。像点在左右图像上的高度一致。这也就是极线校正的目标。校正后做后续的立体匹配时,只需在同一行上搜索左右像平面的匹配点即可,能使效率大大提高。

    Bouguet的方法是一种标定立体矫正方法,需要实现对左右相机进行标定,是将OPencv求解出来的旋转和平移矩阵分解成左右相机各旋转一半的旋转和平移矩阵R1,T1与R2,T2。分解的原则是使得,左右图像重投影造成的畸变最小,左右视图的共同面积最大。

    1、将右图像平面相对于左图像平面的旋转矩阵分解成两个矩阵Rl和Rr,叫做左右相机的合成旋转矩阵。将左右相机各旋转一半,使得左右相机的光轴平行。此时左右相机的成像面达到平行,但是基线与成像平面不平行(行不对准)。
    在这里插入图片描述

    此时两个矩阵满足以下关系,通过这个关系可以看出来rl和rr是正交阵
    在这里插入图片描述

    2、构造变换矩阵Rrect使得基线与成像平面平行(行对准)。构造的方法是通过右相机相对于左相机的偏移矩阵T完成的。

    (1)首先先创建一个由极点el方向开始的旋转矩阵,令主点(cx,cy)为左图像原点,则极点el的方向就是相机投影中心之间的平移向量方向.
    在这里插入图片描述

    (2)e2方向与主光轴方向正交,沿图像方向,与e1垂直,则知e2方向可通过e1与主光轴方向的叉积并归一化获得。
    在这里插入图片描述
    (3)获取了e1与e2后,e3与e1和e2正交,e3自然就是他们两个的叉积:
    在这里插入图片描述

    Rrect如下:
    在这里插入图片描述

    (4)通过合成旋转矩阵与变换矩阵相乘获得左右相机的整体旋转矩阵。左右相机坐标系乘以各自的整体旋转矩阵就可使得左右相机的主光轴平行,且像平面与基线平行。
    在这里插入图片描述

    3.通过上述的两个整体旋转矩阵,就能够得到理想的平行配置的双目立体系图像。校正后根据需要对图像进行裁剪,需重新选择一个图像中心,和图像边缘从而让左、右叠加部分最大。

    使用MATLAB对图像进行校正
    一般我们拍的双目图像不是行对齐的,存在偏差,通过使用相机标定文件对图片进行校正。

    if(~exist('stereoParams.mat'))
        load('stereoParams.mat');
    end
    load stereoParams.mat
    for i = 0:22  
        img1=imread(['./l/00000',num2str(i),'_10.png']);
        img2=imread(['./r/00000',num2str(i),'_10.png']);
        [J1,J2]=rectifyStereoImages(img1,img2,stereoParams,'OutputView','valid');  
        imwrite(J1,['./l_rec/00000',num2str(i),'_10.png']);
        imwrite(J2,['./r_rec/00000',num2str(i),'_10.png']);
    end
    disp("Finished! ")
    % img1 = imresize(img1,[489,734]);
    % img2 = imresize(img2,[489,734]);
    %figure,imshow(img1);
    

    注意两点:

    1. matlab中for循环编写:
      循环结构:for语句
      格式:
      for 循环变量=表达式1:表达式2:表达式3
      循环体
      end
      【注】:
      表达式1:循环变量初值,
      表达式2:步长,为1时,可省略;
      表达式3:循环变量终值,会参与到计算。

    2.字符串拼接
    这里使用[]和,来完成。

    参考链接:
    https://www.cnblogs.com/zyly/p/9373991.html
    线结构光传感器标定(相机标定+结构光标定)完整流程(一)
    UR机器人手眼标定(二)

    展开全文
  • 双目相机模型

    千次阅读 2020-11-03 09:53:47
    近期想研究一下 双目相机 的内容,故先把 理论 弄清楚! 一、双目相机模型 针孔相机模型描述了 单个相机 的成像模型。然而,仅根据一个像素,我们是无法确定 这个空间点的具体位置的。这是因为,从相机光心到...
  • 双目相机视差测距

    2022-04-06 11:33:04
    双目相机视差测距
  • 本文承接ROS调用USB双目摄像头模组 注意,遇到了点问题,还没写完!!! 按照上面链接配置好后,执行 rostopic list 你应该可以找到两个比较关键的节点:/left_cam/image_raw 和 /right_cam/image_raw 先完成单...
  • 用QT以及vs2013,opencv2.4.9写的一个验证双目相机拍摄图片是否延时的程序。拍摄的照片会保存起来。计时为毫秒级。
  • 本文属于个人笔记,不具备参考价值 ,请勿使用 文章参考链接1 文章参考链接2 一、深度相机的介绍  随着机器视觉与人工智能等技术的飞速发展,采用场景建模... 结构光的提出也是为了解决RGB双目相机所存在的问题...
  • 双目相机基本原理

    2022-04-12 16:17:28
    双目相机基本原理
  • python调用相机和双目相机

    千次阅读 2022-04-25 14:45:06
    python调用相机 import cv2 import numpy as np cap = cv2.VideoCapture(0) ret, frame = cap.read() while ret: ret, frame = cap.read() cv2.imshow("frame", frame) if cv2.waitKey(1) & 0xFF == ord('q')...
  • 双目相机矫正matlab c++ cpp 双目标定及矫正系列文章更新,C/CPP实现双目矫正(不使用OpenCV)及矫正源码解析。 matlab标定较为准确,命令行中输入stereoCameraCalibrator enter 添加左图 右图 确定 选择畸变参数,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,133
精华内容 4,453
关键字:

双目相机

友情链接: 求内参.zip