双目立体视觉:四(双目标定matlab,图像校正,图像匹配,计算视差,disparity详解,)

二郎也比较忙,在某大场工作,有时候没有时间回复。
如果希望二郎尽快帮忙,可以将代码,数据和问题发给二郎,谢谢大家理解。
glwang20@mails.jlu.edu.cn
不过还是希望大家自己要好好研究,问二郎太基础性的问题,证明自己没有看过书籍,二郎就有一点点不太想回复了。
首先说明一点,需要用到matlab的stereoCameraCalibrator算法,该算法在2014a版本后添加的,因此之前的版本找不到,所以还是安装一个新版本的吧,我装的2016a。
这里说一下,换2016a可能会遇到打开图片特别慢,这里需要切换一下软件
opengl software(在matlab中执行)
切回硬件
opengl hardware
测试有没有stereo可以输入Enter stereoCameraCalibrator
我们在使用双目相机时,首先需要进行标定(就是相机有误差,我们需要消掉误差,如何消掉?加几个参数调节)

这里还要说明一个问题,有些人询问二郎为啥校正后图像会被截去很多,这里有几个原因:
1)相机畸变较大,两个相机的摆放位置偏差较大,截去较多是正常现象,不影响后期的匹配和距离计算。
2)如果后期出现了问题,则需要考虑是否把高阶畸变参数去掉,k3。
3)相机的摆放位置对其影响较大,应尽可能将两台相机放在同一直线上(光轴平行)。应尽可能避免使用两个性能不同的相机或者参数不一致的相机。

双目标定的流程

在这里插入图片描述
基本上按这个就可得到我们想要的校正双目误差的参数了。
下面强调几点过程中的注意事项
1.拍摄的图片是棋牌格,棋盘格的外围需要是长方形,不能是正方形,要不matlab会报数据错误。
2.在计算完成后注意保存mat
下面是流程图
在这里插入图片描述
然后将上面的“Skew”、“Tangential Distortion”以及“3 Coefficients”等选项选上,将“2 Coefficients”选项去掉(如果在接下来的步骤,你的参数有问题或者校正后的图像对异常,请去掉第三个参数,直接选择2 Coefficirents,因为在我们标定板精度不高时,采用较高的畸变参数可能会出现问题。)(这里图上为了方便直接默认着的):
在这里插入图片描述
Camera1代表左摄像头,Camera2代表右摄像头
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
保存后的参数在matlab的文件目录下,关掉该窗口后你就能看到
到这,我们的相机标定就结束了,我们最后得到一个mat文件。
mat文件解释
CameraParameters1为左摄像头的单独标定参数,CameraParameters2为右摄像头的单独标定参数。

stereoParams.TranslationOfCamera2:可以直接使用。
stereoParams.RotationOfCamera2:如需要在其他地方使用该矩阵,需转置以后使用(这里需要注意是用在哪里,转置后只是和我们平常见到的形式保持一致,方便我们分析,如果不导出直接在matlab中应用,多数情况下没有必要转置)。
在这里插入图片描述
CameraParameters1/CameraParameters2内
在这里插入图片描述
RadialDistortion:径向畸变,来源于光学透镜的特性,由K1,K2,K3确定。
TangentialDistortion:切向畸变,相机装配误差,传感器与光学镜头非完全平行,由两个参数P1,P2确定。
参数排序K1,K2,P1,P2,K3。
这里需要把我们的标定结果保存为mat,方便以后应用
save(‘my1stereoParams.mat’ , ‘stereoParams’);

图像校正流程

标定后,图像的校正其实非常简单,只需要代入函数即可

clear all
clc

I1 = imread('zed_left2.png');%读取左右图片
I2 = imread('zed_right2.png');
figure
imshowpair(I1, I2, 'montage');
title('Original Images');

%加载stereoParameters对象。
load('my1stereoParams.mat');%加载你保存的相机标定的mat

[J1, J2] = rectifyStereoImages(I1, I2, stereoParams);
figure
imshowpair(J1, J2, 'montage');
title('Undistorted Images');

立体图像校正将图像投影到共同的图像平面上,使得对应的点具有相同的行坐标。
我们完成了校正之后,我们再进行特征点匹配就能将两张图联系到一起,进而求得距离信息。
很多做法中,校正后需要看一下校正的结果,把第一个图像的红通道和第二个图像的蓝通道和绿通道结合构成图像,可以看出浅浅的叠影,红色的就是我们的图1,其他色的就是我们的图2

figure; imshow(cat(3, J1(:,:,1), J2(:,:,2:3)), 'InitialMagnification', 50);%图像显示50%

或者也可以用二郎写的一个程序,挺有意思的,让两个物体同时显示,利用到(图像融合,边缘提取)

WL1 = abs(imfilter(rgb2gray(J1), fspecial('Laplacian'), 'replicate', 'conv'));
WL2 = abs(imfilter(rgb2gray(J2), fspecial('Laplacian'), 'replicate', 'conv'));
WL1(WL1(:)>=WL2(:)) = 1;WL1(WL1(:)<WL2(:)) = 0;
WL2(WL1(:)>=WL2(:)) = 0;WL2(WL1(:)<WL2(:)) = 1;
J_F(:,:,1) = J1(:,:,1).*WL1+J2(:,:,1).*WL2;
J_F(:,:,2) = J1(:,:,2).*WL1+J2(:,:,2).*WL2;
J_F(:,:,3) = J1(:,:,3).*WL1+J2(:,:,3).*WL2;
figure; imshow(J_F, 'InitialMagnification', 50);%图像显示50%

计算视差图disparity(matlab)

二郎从网上看到好多,然而大部分有点想吐槽,都是罗列一堆公式……让人怎们看……这里二郎整理一下,包括公式解答和计算视差所用的算法(二郎之前也想过,它的计算视差,是已经内嵌了匹配了??往下看吧)

disparityMap = disparity(rgb2gray(J1), rgb2gray(J2), 'BlockSize',... 
'15',DisparityRange',[0,400],'BlockSize',15,'ContrastThreshold',0.5,'UniquenessThreshold',15);

上面的一大串是二郎平时用的,这里先说明一下,该算法的操作对象均为灰度图,因此用到了两个rgb2gray;如何看懂一个函数最主要的是明白它的输入是什么,可设参数是什么,输出是什么。
该函数的输入是

rgb2gray(J1), rgb2gray(J2),

可设参数是

'DisparityRange',[0,400],'BlockSize',15,'ContrastThreshold',0.5,'UniquenessThreshold',15

其中:
’BlockMatching’或’SemiGlobal’:视差估计算法的一种(该种算法为默认算法),通过比较图像中每个像素块的绝对差值之和(SAD)来计算视差。
(块匹配采用了基本块匹配1.Konolige,K。,Small Vision Systems:Hardware and Implementation,Proceedings of the 8th International Symposium in Robotic Research,pages 203-212,1997。或者半全局块匹配2.Hirschmuller, H., Accurate and Efficient Stereo Processing by Semi-Global Matching and Mutual Information, International Conference on Computer Vision and Pattern Recognition, 2005.)

’DisparityRange’,[0,400]:视差范围,范围可以自己设定,不能超过图像的尺寸,当双目距离较远或者物体距离较近时,应适当增大该参数的值。

’BlockSize’, 15:设置匹配时方块大小。

’ContrastThreshold’,0.5:对比度的阈值,阈值越大,错误匹配点越少,能匹配到的点也越少。

’UniquenessThreshold’,15:唯一性阈值,设置值越大,越破坏了像素的唯一性,设置为0,禁用该参数。

’DistanceThreshold’,400:从图像左侧到右侧检测的最大跨度,跨度越小越准确,但很容易造成无法匹配。禁用该参数[]。

’TextureThreshold’,0.0002(默认):最小纹理阈值,定义最小的可靠纹理,越大越造成匹配点少,越少越容易匹配到小纹理,引起误差。

输出是

disparityMap

返回的视差值,以图1为底板,以图2与图1的视差为灰度值。

整体计算的步骤:
1.使用Sobel滤波器计算图像对比度的度量。
2.通过使用块匹配和绝对差值之和(SAD)来计算每个像素的视差。
3.标记包含不可靠的像素 差异值。该函数将像素设置为 - realmax(’ single’)返回的值。

显示 disparityMap

多数情况下该图显示为彩色的更为直观

figure;imshow(disparityMap, [0, 400]);
title('Disparity Map');
colormap jet
colorbar

从视差图中提取三维信息

pointCloud3D = reconstructScene(disparityMap, stereoParams);

这里有两个参数,第一个为我们计算的视差图,第二个是我们利用matlab对两个相机进行标定后的标定文件。这里matlab已经集成,没有文档说明采用的什么策略。
返回的矩阵 pointCloud3D为三维,(:,:,1)x坐标,(:,:,2)y坐标,(:,:,3)z坐标。
这里需要注意,出来的参数类型是single,这里最好转化一下(single占用4个字节、double占用8个字节,single所需空间比double少,但是在特殊场合精度不够。但是matlab中一些自带的优化主要针对的double,虽然single占内存小,但是它并不一定比double快。)

 pointCloud3D = double(pointCloud3D);

还有,我们出来的数的单位均为厘米,因此为了方便,我们需要转化为米来使用

 pointCloud3D = pointCloud3D/100;

显示距离和图像

Z = double(pointCloud3D(:,:,3));
mask = repmat(Z> 5&Z <6,[1,1,3]);
J1(~mask)= 0;
figure;imshow(J1,'InitialMagnification',50);

这里的50指定了显示的时候放大倍数为50%,也就是缩小一半放大。
这里显示的是距离5~6米之间的物体,其他范围的物体都变成了黑色
在这里插入图片描述

  • 133
    点赞
  • 969
    收藏
    觉得还不错? 一键收藏
  • 197
    评论
MATLAB中,你可以使用Computer Vision Toolbox提供的函数来实现双目视觉图像校正。以下是一个基本的步骤示例: 1. 相机标定:使用`stereoCameraCalibrator`函数对左右相机进行标定,得到相机的内外参数。该函数将引导你在多个图像中选择标定点,并自动计算相机参数。 ```matlab % 读取左右相机图像 leftImages = imageDatastore('path_to_left_images'); rightImages = imageDatastore('path_to_right_images'); % 进行相机标定 stereoParams = stereoCameraCalibrator(leftImages, rightImages); ``` 2. 双目校正:使用`stereoRectify`函数根据相机参数计算校正变换,得到校正后的投影矩阵。 ```matlab % 计算校正变换 [stereoParams, rectifiedParams] = stereoRectify(stereoParams);``` 3. 畸变校正:使用`undistortImage`函数对左右图像进行畸变校正。 ```matlab % 读取待校正图像 leftImage = imread('path_to_left_image'); rightImage = imread('path_to_right_image'); % 对图像进行畸变校正 rectifiedLeftImage = undistortImage(leftImage, stereoParams.CameraParameters1); rectifiedRightImage = undistortImage(rightImage, stereoParams.CameraParameters2); ``` 4. 极线对齐:使用`rectifyStereoImages`函数对校正后的图像进行极线对齐。 ```matlab % 对校正后的图像进行极线对齐 [rectifiedLeftImage, rectifiedRightImage] = rectifyStereoImages(rectifiedLeftImage, rectifiedRightImage, rectifiedParams); ``` 完成以上步骤后,你将获得校正后的左右图像,可以使用它们进行后续的视差计算和深度估计等任务。请注意,这只是一个简单示例,实际的双目视觉校正过程可能会更复杂,涉及更多的参数和技术。你可以参考MATLAB文档和示例代码以获得更详细的信息。
评论 197
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值