双目成像技术是利用机器视觉,通过两个相机同时同步对图片进行采集,获取左右两相机对一幅图像的对应点成像的像素差获取深度信息,进而获取三维信息,来实现对物体的重建。该技术在现有阶段只能对短距离的物体进行测距与三维重建。在我看来,要对双目成像技术有进一步提升的点就在于测距的深度以及三维重建的准确信与稳定性。对于双目成像技术最重要的莫过于对相机拍摄的图片的处理。图像的预处理直接决定了立体匹配与深度预测的效果。想要有所突破,应当在图像处理上进行推敲。下面我将对双目成像技术展开叙述自己的所学所见所悟,对自己进行沉淀也希望能对他人有所帮助。
1、图像获取
为了确保左右两相机所拍摄场景的一致性,双目相机采用同时采集。即同时同地一齐采集。获取的图片随着相机的焦距变化而变化。加大光学焦距会缩小成像视场范围,且受体积限制;增大双目系统的基线距离,不仅受到系统体积的限制,而且会增大双目成像的视野盲区,增大标定难度。
2、相机标定
2.1 相机标定的原因
相机标定主要目的在于获得相机的参数。相机自带的参数属于理想参数,与实际的相机参数有所差别。在镜头的安装与组装时对镜头的偏差导致透镜本身与图像并非完全平行,即切向畸变。还有光线在透镜中心的地方比靠近中心的地方更加弯曲产生径向畸变。同时通过对相机的标定建立起一个“三维—二维”“二维—三维”的映射关系,来获取原来物体的三维信息。
2.2 四个坐标系的介绍
世界坐标系:描述目标物体在真实世界的位置而引入的三维世界坐标系。
相机坐标系:以相机为中心,从相机角度描述物体位置,作为像素坐标系—世界坐标系的桥梁。
图像坐标系:描述真实物体在相机焦距处成像的坐标系,用来连接相机坐标系与像素坐标系。
像素坐标系:描述物体在照片上数字图像的位置而引入的一种数字坐标系。
2.3 四个坐标系的相互转化关系
图像坐标系与像素坐标系转换
相机中感光器件的每个像素物理尺寸为dx*dy,则图像坐标系中的坐标(x,y)与像素坐标系中的坐标(u,v)之间的关系可以表示为:
改写成为矩阵的格式为:
相机坐标系与图像坐标系转换
相机坐标系以相机的光轴作为Z轴,光线在相机的光学系统中心位置就是远点Oc,相机坐标系的Xc、Yc与图像坐标系的X、Y平行。相机坐标系原点与图像坐标系的原点之间的距离Oc、Of之间的距离就是焦距f
相机坐标系与世界坐标系的转换
相机坐标系与世界坐标系的转化主要通过旋转矩阵以及平移矩阵来获得相机坐标系与世界坐标系的对应关系,具体映射关系如下:
像素坐标系与世界坐标系的转换
以上三个坐标系的转换相乘即可得出像素坐标系与世界坐标系的对应关系:
将fx=f/dx、fy=f/dy带入得到最终的表达式:
2.4 三角测量原理
规定al和ar之间的距离为x,因为al在al对应的相机坐标系下为正值,ar在ar对应的相机坐标系下为负值,所以x的值为b减正加负,即x=b-al+ar。
由三角相似原理得:
将x=b-al+ar带入得:
规定S为图像坐标系下每单位mm的像素个数,U0、V0为图像坐标系原点在像素坐标系下的位置,则由图像坐标系与像素坐标系的关系得:
将Xp_l与Xp_r的两个式子相减变换得到:
将Z的表达式带入上式得:
fx定义为f与S的乘积,通过上式能够看出只要能够获取到一个像素值在左右两相机的像素差,结合相机的焦距以及基线距离,就能获取到对应物体的深度。
同理在X、Y方向上根据相机坐标系与图片坐标系的相似关系能够得到:
可得:
综上可知,如果知道对应点在左右两相机的视差(Xp_l—Xp_r),就能恢复图像在相机坐标系下的三维坐标,进而根据四大坐标系的关系,映射出在世界坐标系的位置,即物体在真实世界的坐标。
2.5 张正友友棋盘格标定法在matlab的实现
首先准备图片集在matlab中进行相机标定,打开matlab,点击上方app,找到Camera Calibrator点击进入,如图:
点击上栏的Add Images 下拉展开项找到From file 将自己的图片集导入其中会显示下图:
设置棋盘格的真实尺寸,然后点击确定,即可看见图片,然后点击Calibrate运行可得到下图:
然后点击Export Camera Parameters展开选择Export Parameters to Workspace,即可在工作区间看见各种相机参数如下图:
3、图像预处理
3.1 图像灰度化
图像灰度化主要包括三个方法:
分量法
取每个像素RGB的任意一种作为该点的灰度值
最大值法
采用Max(R,G,B)作为灰度值
平均值法
采用Avg(R,G,B)作为灰度值
加权平均法
将R、G、B以权重相加作为灰度值
3.2 图像平滑
主要介绍图像滤的方法,分类如下图:
均值滤波
将某点像素值用周围固定大小像素的平均值代替(类似卷积核),不能完全消除噪声,只能相对减弱噪声,同时会对图像进行模糊,无法确定图像的边缘特征和具体细节。
中值滤波
将某点像素值用周围固定大小像素的中值代替(类似卷积核),对噪声不是很敏感,容易导致图像的不连续性。
高斯滤波
将领域内相邻像素点计算高斯加权平均值,即选取一定大小,设置均方差,带入点坐标算出对应的权重,归一化与对应的像素值相乘相加代表中心的像素值,二维高斯公式如下:
x、y表示的是领域范围内其他像素点与中心像素点的距离,σ代表标准差。
3.3 图像增强
自适应对比增强算法
自适应对比增强算法采用了反锐化掩模技术,将图像分为高频和低频两个部分,低频代表的是反锐化掩模部分,通过低通滤波得到,高频分量通过原始图像减去低频分量得到。ACE算法主要将高频分量进行对比度增益,然后与低频相加,得到增强图像。
定义一个窗口的大小为(2n+1)*(2n+1),n为一个整数,局部的平均值就是低频部分,于是可以得到低频分量为:
局部方差为:
则ACE算法可以表示为:
G(i,j)是放大系数即为对比增益CG。
Retinex算法
根据人眼识别物体的原理,人眼的一幅图像f(x,y)的成像主要由入射光图像L(x,y)和反射体图像R(x,y)决定
f(x,y)= L(x,y)R(x,y)
将上式取对数,变换得反射体图像:
入射光部分为可以通过原始图像与环绕函数g(x,y)的卷积得到
g(x,y)一般取高斯核函数
则Retinex增强模型可以表示为:
以上为单尺度Retinex增强模型(SSR),σ越大,增强效果越明显;σ越小,图像增强细节明显,容易输出颜色失真。
多尺度Retinex算法(MSR):
Wk为高斯核函数的权重值,和为1。
3.4 图像分割
基于阈值的分割方法
通过计算图像整体的灰度值确定一个灰度阈值,将图像中的每一个灰度值斗鱼图像灰度阈值进行比较,进行区域分割。
基于边缘的分割方法
图像边缘显示的是图像部分区域所表示的不连续性。相邻像素点具有相同的灰度值,则可以通过像素点连接起来形成边缘。通过对整张图片的像素点灰度值的提取,会在图像上产生大量的灰度边缘曲线。
基于区域的分割方法
在图片上的各区域块具有不同的纹理。将领域内一致性的像素点归纳为一个区域块。
OTSU二值分割阈值算法
OTSU二值分割阈值算法根据图像的灰度值阈值将图像分为前景和背景两部分。通过计算前景和背景的类间方差来衡量分割效果。图像前景和背景两部分差异越大,类间方差越大,分割效果越好。因此OTSU的目标就是寻找使得类间方差最大的灰度阈值。
假设存在阈值TH将图片分为两类,一类为C1(前景小于TH),一类为C2(背景大于TH)。设前景像素占整幅图的比例为W0,平均灰度为U0;背景像素占整幅图的比例为W1,平均灰度值为U1。图像总平均像素为U,类间方差记为σ。设图像大小为MxN,则灰度值小于阈值的个数记为N0,大于阈值的个数记为N1,则有:
W0 = N0/(MXN)
W1 = N1/(MxN)
N0 + N1= MxN W0+W1 = 1
U = W0*N0 + W1*N1
σ = W0(U0-U)²+W1*(U1-U)
带入得类方间误差的表达式为:σ = W1*W2*(U0-U1)²
我使用python进行测试遍历出阈值大小,具体代码如下:
import numpy as npfrom PIL import Image# open里面的内容为图片保存位置的绝对路径im = Image.open('1636097391100.jpg').convert('L') def otsu_threshold(im):width, height = im.sizeimg_size = width * heightpixel_counts = np.zeros(256)for x in range(width):for y in range(height):pixel = im.getpixel((x, y))pixel_counts[pixel] = pixel_counts[pixel] + 1# 得到图片的以0-255索引的像素值个数列表s_max = (0, -10)for threshold in range(256):# 遍历所有阈值# 更新n_0 = sum(pixel_counts[:threshold]) # 得到阈值以下像素个数n_1 = sum(pixel_counts[threshold:]) # 得到阈值以上像素个数w_0 = n_0 / img_sizew_1 = n_1 / img_size# 得到阈值下所有像素的平均灰度u_0 = sum([i * pixel_counts[i] for i in range(0, threshold)]) / n_0 if n_0 > 0 else 0# 得到阈值上所有像素的平均灰度u_1 = sum([i * pixel_counts[i] for i in range(threshold, 256)]) / n_1 if n_1 > 0 else 0# 总平均灰度u = w_0 * u_0 + w_1 * u_1# 类间方差g = w_0 * (u_0 - u) * (u_0 - u) + w_1 * (u_1 - u) * (u_1 - u)# 类间方差等价公式# g = w_0 * w_1 * (u_0 * u_1) * (u_0 * u_1)# 取最大的if g > s_max[1]:s_max = (threshold, g)return s_max[0]print(otsu_threshold(im))
添加图片便利结果为0-255的一个灰度值,如下图:
3.5 超分辨率图像重建
双目视觉的测距误差随着距离增大而增大。降低测距误差的主要途径包括增加光学系统焦距,增大双目系统的基线距离和提高系统的成像质量。加大光学焦距会缩小成像视场范围,且受系统体积限制;增大双目系统的基线不仅会受到系统体积限制,而且会减小双目视场交汇区域,增大视野盲区,加大系统标定的难度。相对于低分辨率图像,高分辨率图像图像通常包括更大的像素密度,更丰富的纹理细节和更高的可信赖度。图像的超分辨率重建指的就是将给定的低分辨率图像通过算法恢复成高分辨率图像。我看了一篇文章他写的超分辨率算法运用在双目视觉里面会有很好的效果,可以使测距达到更大的范围,且鲁棒性较好。唯一的我不知道的地方是超分辨率图像重建后对应点的像素值有没有发生改变。不过我猜测是没有发生改变,因为超分辨率图像重建是基于已知点的模型映射或者线性插值,能反映图像的特点。具体的超分辨率图像重建方法会在写一篇文章详细说明。
4、立体匹配
4.1 立体匹配的分类
基于区域约束的局部匹配算法
首先选取左摄像机采集图像上的某一个像素点,然后以该像素点为中心选取一个范围的区域作为待匹配的区域,在右摄像机上寻找相似度高的匹配区域,然后在该匹配区域中特征最相似的像素点就为改像素的匹配点,然后利用局部优化函数对视差进行估计。该方法的关键是窗口大小的选择。
基于特征的立体匹配算法
该方法通过提取物体的角点、边缘和平面的局部特征,或者提取复杂形状和整体图像结构的全局特征,然后对左右两摄像头采集到的图像进行特征匹配,从而可以获得较为稀疏的视差图。这种匹配算法的优点在于匹配精度的选定,提取特征对光照的敏感度低,估计差值所需要的时间长。
基于全局约束的优化匹配算法
全局立体匹配算法利用图像的全局约束信息,建立全局能量函数,通过优化计算法最小化全局能量函数得到稠密的视差图。。运算时间长,误匹配率高,实时性比较差。
4.2 立体匹配算法实现过程
立体匹配的实现过程主要包括匹配代价计算,代价聚合,计算视差,视差精化。
1)匹配代价函数
常用的就是基于像素点匹配代价计算,通过计算多种视差下像素点的灰度值视差,比较灰度值相似度来实现。匹配代价计算会生成一个三维的空间控件图像,每一个视差就可以得到一张视差图,然后在视差范围内搜索匹配代价图,通过比较得到匹配代价最小的视差即为此像素对应的视差。
2)代价聚合
在匹配代价计算得到的图像上的像素的视差值是相互独立的,会因为引入噪声产生干扰,使得该区域内的视差值产生差异,因此我们需要通过窗口卷积对匹配代价计算得到的数据进行滤波处理。
3)计算视差
在局部区域匹配中,通常采用的方法是WTA算法,对于图像局部区域的同一个像素点,选取代价图中匹配代价最小的像素点所对应的代价图,该像素点的视差值即为最终的视差值。
全局立体匹配是对整幅图像进行数据分析的,使用能量函数获取数据项和平滑项,数据项为代价计算,平滑项为代价聚合。全局立体匹配与局部立体匹配的区别在于是否有平滑项。
4)视差精化
视差精化是为了满足某些高精度要求,经过视差精化可以使得视差图的精度会略微提高,属于立体匹配的优化环节。
5、三维信息重建
三维信息的重建其实是根据相机中的像素关系,或者图片的灰度值、纹理等一些特征对物体在空间中进行重建。
5.1 被动式三维重建
纹理恢复形状法
通过提取物体表面特有的纹理特征,进而确定目标物体的表面属性,从而得到目标物体的表面三维形状。鲁棒性较差,在实际应用中并不可取。
阴影恢复形状法
通过提取物体表面的阴影边界信息和轮廓特征信息,获取图像的明暗程度以及阴影边界信息来计算物体深度来实现三维重建。该算法需要稳定的光源作为参考,同时需要在密闭的空间,不能再曝光环境以及复杂环境下取得良好效果。
立体视觉法
该方法利用对应点与基准情况对比后的位置偏差获取三维信息,主要是获取同一物体在同一时刻在不同的角度同时拍摄的图片的对应点的视差来恢复物体的三维信息。
5.2 主动式三维重建
莫尔条纹法
将两个空间频率一致的周期光栅重叠起来,以一个很小的角度进行相互倾斜重叠来形成莫尔条纹。根据条纹的相位信息过去到待测的目标物体的深度信息,然后通过逆向的解调函数便可以实现对于目标物体的深度信息恢复。该方法精度高、实时性很强,但是对光照敏感,抗干扰能力弱。
飞行时间法
通过传感器发射信号到接收信号之间的往返飞行时间间隔测量两者的距离。成像速度快,操作便捷,实时性高。
结构光法
通过对表面光滑的目标物体发射经特殊偏码图案或特征点的光源,通过提取光源所附带的特殊编码图案和特征点,适用于光照不足,缺乏纹理的环境中,对于高分辨率的深度图像有很好的效果。
三角测距法
通过红外发射器以一定的角度向物体发射红外线光,预先放置的CCD图像传感器可以接收到从目标物体表面反射回来的红外光线。当目标物体发生移动时,反射光线也会产生相应的偏移,在CCD图像传感器上就可以得到相应的偏移距离。
6、心得与体会
学习了双目成像技术,总的感受是在生活中容易忽略的东西都能在计算机中发挥重大的作用。比如说物体表面的纹理,物体的反射光,物体的边缘结构,一些能够侧面反映物体属性的东西都被运用在对物体进行三维重建上。如果让我运用双目成像技术,我会用双目相机对图像进行采集,用张正友棋盘格标定法相机进行标定,进行立体校正,保证图片在同一平面上,对应点在极线上。接着对图像进行预处理,将图像进行超分辨率重建技术获取更多更加清晰的局部特征。在此如果只是想获取在两个物体之间的安全距离,可以通过图像分割以及拉普拉斯算子对图像进行锐化处理,丰富图片的边缘信息,通过边缘信息在图片中的距离来获取真实场景中的距离。如果是想要用来测深度,对图像进行灰度化,采用中值滤波后进行高斯滤波,获取左右两相机的视差,通过视差还原物体的深度信息。如果要还原物体在三维世界的立体模型,完成三维信息重建。要对图像进行超分辨率重建,然后对图像进行加权平均值灰度化,然后采用Retinex算法对图像进行低光增强同时对图像进行分割,准确的的获取更多的特征对应点,来根据视差获取深度信息,然后通过速度较快的SAD图像匹配算法进行立体匹配。我觉得双目成像技术因为双目相机的基线信息和焦距属于相机的内部参数,只能通过一些机器学习深度学习算法来实现对网络模型的优化以及升级。在我看来这比较困难,相对简单的突破是在对于图像的处理上进行突破,能够在远距离图像获取更多的特征点与匹配信息,就能获得更高的精度和鲁棒性。超分辨率图像重建能够将远处低分辨率图像重建成高分辨率图像,就能有更多的特征信息,以及更准确地视差信息,即可以再三维立体重建中获取更好的效果。