赞
踩
因为在自己的工作中需要剔除行驶的地面,要用到U-V视差,所以写这篇博客主要是记录自己学习到的相关内容。如果写的有问题可以在评论中指出。
实践部分
目录
双目相机系统如下图所示:f为焦距,b为基线,P(X,Y,Z)为三维点。 我们可以得到视差的公式如下:(双目视觉系统)
首先,当我们使用双目相机拍摄真实世界时,如下图所示,(Xw ,Yw , Zw )为世界坐标系,(Xl ,Yl , Zl)为左相机坐标系,(Xr ,Yr , Zr)为右相机坐标系。
那么,从世界坐标系到左右相机坐标的变换矩阵为:
其次,我们预先通过标定知道了左右相机的内参矩阵为:
当相机的内参和外参都知道了,根据针孔相机模型,就可以计算处相机的投影矩阵P=K[R|t]
使用矩阵的乘法公式对其进行展开得到:
由d=ul-ur得到视差:
U-disparityMap的列对应于原始视差图的列;
U-disparityMap中(d,u) = 原始视差图中第u列,视差为d的个数。
V-disparityMap的行对应于原始视差图的行;
V-disparityMap中(v,d) = 原始视差图中第v行,视差为d的个数。
1.左图像,右图像,视差图像
2.U-视差,V-视差
3.对U-V视差图使用霍夫变换检测线
①,⑤:近似直线,如图中的球体和圆锥;
② 11:地平面在V视差中的投影为直线;
⑥,⑦:侧面的墙在U视差中的投影为直线;
⑨ :垂直障碍物;
③④⑧⑩:垂直墙面的转角处;
4.3D重建的结构
- //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);
- 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)++;
- }
- }
- }
- }
- 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)++;
- }
-
- }
- }
- }
- 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
视差:disparity与UV-视差:UV-disparity_uv视差图_生活没有if-else的博客-CSDN博客
菜鸟看论文——U-V-Disparity与地面检测、相机姿态估计:菜鸟看论文——U-V-Disparity与地面检测、相机姿态估计_yiteeee的博客-CSDN博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。