双目视觉(六)U-V视差

系列文章:

  1. 双目视觉(一)双目视觉系统
  2. 双目视觉(二)双目匹配的困难和评判标准
  3. 双目视觉(三)立体匹配算法
  4. 双目视觉(四)匹配代价
  5. 双目视觉(五)立体匹配算法之动态规划全局匹配
  6. 双目视觉(六)U-V视差
  7. 【项目实战】利用U-V视差进行地面检测
  8. 【项目实践】U-V视差路面检测之动态规划

因为在自己的工作中需要剔除行驶的地面,要用到U-V视差,所以写这篇博客主要是记录自己学习到的相关内容。如果写的有问题可以在评论中指出。

实践部分

  1. 【项目实战】利用U-V视差进行地面检测【链接
  2. 【项目实践】U-V视差路面检测之动态规划【链接

  3. 【项目实践】开源代码【链接

目录

1.原理:

双目系统

模型推导 

2.U-V视差的构造

3.各种3D平面在U-V视差中的投影 

4.实例 

5.Opencv实现

 参考:


1.原理:

  • 双目系统

双目相机系统如下图所示:f为焦距,b为基线,P(X,Y,Z)为三维点。 我们可以得到视差的公式如下:(双目视觉系统

  • 模型推导 

首先,当我们使用双目相机拍摄真实世界时,如下图所示,(Xw ,Yw , Zw )为世界坐标系,(Xl ,Yl , Zl)为左相机坐标系,(Xr ,Yr , Zr)为右相机坐标系。 

  • 对于世界坐标系和左相机坐标系,存在着b/2的平移,以及一个旋转角θ
  • 对于世界坐标系和右相机坐标系,存在着b/2的平移,以及一个旋转角θ

那么,从世界坐标系到左右相机坐标的变换矩阵为:

 其次,我们预先通过标定知道了左右相机的内参矩阵为:

 当相机的内参和外参都知道了,根据针孔相机模型,就可以计算处相机的投影矩阵P=K[R|t]

使用矩阵的乘法公式对其进行展开得到: 

 由d=ul-ur得到视差:

2.U-V视差的构造

  • U视差的构造

U-disparityMap的列对应于原始视差图的列;

U-disparityMap中(d,u) = 原始视差图中第u列,视差为d的个数。

  • V视差的构造

V-disparityMap的行对应于原始视差图的行;

V-disparityMap中(v,d) = 原始视差图中第v行,视差为d的个数。

3.各种3D平面在U-V视差中的投影 

4.实例 

1.左图像,右图像,视差图像

 2.U-视差,V-视差

3.对U-V视差图使用霍夫变换检测线

 

①,⑤:近似直线,如图中的球体和圆锥;

②   11:地平面在V视差中的投影为直线;

⑥,⑦:侧面的墙在U视差中的投影为直线;

⑨       :垂直障碍物;

③④⑧⑩:垂直墙面的转角处;

4.3D重建的结构

5.Opencv实现

  • 双目匹配(这里我们使用Opencv中自带的SGBM算法)
    //SGBM param
    int mMaxDisp = 128;
    int mP1 = 100;
    int mP2 = 2700;
    int mWinSize = 4;
    int mPreFilterCap = 180;

    //create SGBM
    cv::Ptr<cv::StereoSGBM> mSGBM=cv::StereoSGBM::create(0,mMaxDisp,mWinSize,mP1,mP2,0,mPreFilterCap,5,0,0,cv::StereoSGBM::MODE_HH);

    // read image
    cv::Mat left=cv::imread("../image/I1_000000.png");
    cv::Mat right=cv::imread("../image/I2_000000.png");
    cv::Mat disp16s,disp;

    //compute disparity
    mSGBM->compute(left,right,disp16s);
    disp16s=disp16s/16;
    disp16s.convertTo(disp,CV_8UC1);
  •  计算U视差图
cv::Mat UdispMap=cv::Mat(mMaxDisp,disp.cols,CV_16UC1);
void computeUDisparity(cv::Mat &UdispMap,cv::Mat disp)
{
    UdispMap.setTo(0);
    int width=disp.cols;
    int height=disp.rows;

    for(int row=0;row<height;row++)
    {
        auto  pRowInDisp=disp.ptr<uchar>(row);
        for(int col=0;col<width;col++)
        {
            uint8_t currDisp=pRowInDisp[col];
            if(currDisp>0&&currDisp<128)
            {
                UdispMap.at<ushort>(currDisp,col)++;
            }
        }
    }
}
  • 计算V视差图
cv::Mat VdispMap=cv::Mat(disp.rows,mMaxDisp,CV_16UC1);
void computeVDisparity(cv::Mat &VdispMap,cv::Mat disp)
{
    VdispMap.setTo(0);
    int width=disp.cols;
    int height=disp.rows;

    for(int row=0;row<height;row++)
    {
        auto  pRowInDisp=disp.ptr<uchar>(row);
        for(int col=0;col<width;col++)
        {
            uint8_t currDisp=pRowInDisp[col];
            if(currDisp>0&&currDisp<128)
            {
                VdispMap.at<ushort>(row,currDisp)++;
            }

        }
    }
}
  • 原图像

  • U视差

  • V视差

  • U视差用来剔除障碍物(10为阈值)
cv::Mat removeObstacle(cv::Mat Disparity,cv::Mat Udisparity)
{
    cv::Mat mObstacleMap;
    mObstacleMap.create(Disparity.rows, Disparity.cols, CV_8UC1);

    mObstacleMap.setTo(0);

    int height = Disparity.rows;
    int width = Disparity.cols;


    for (int v = 0; v < height; v++)
    {
        uint8_t* pRowInDisp = Disparity.ptr<uchar>(v);
        uint8_t* pRowInObsMap = mObstacleMap.ptr<uchar>(v);
        for (int u = 0; u < width; u++)
        {
            uint8_t currDisp = pRowInDisp[u];
            if (currDisp < 128 && Udisparity.at<ushort>(currDisp, u) > 10)
                pRowInObsMap[u] = 255;
        }
    }
    return mObstacleMap;

}

 参考:

基于 U-V 视差算法的障碍物识别技术研究

A Complete U-V-Disparity Study for Stereovision Based 3D Driving Environment analysis

基于U—V 视差算法的障碍物识别技术研究 - 道客巴巴

视差:disparity与UV-视差:UV-disparity_uv视差图_生活没有if-else的博客-CSDN博客

菜鸟看论文——U-V-Disparity与地面检测、相机姿态估计:菜鸟看论文——U-V-Disparity与地面检测、相机姿态估计_yiteeee的博客-CSDN博客

可行使区域检测:https://github.com/OdingdongO/bdd_segmentation

可行驶区域检测

评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火柴的初心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值