双目立体视觉建立深度图_计算机视觉实验五 双目立体匹配获得视差图,深度图...
该论文研究了立体匹配算法及其在立体视觉中的应用,重点介绍了基于灰度的区域相关匹配算法。该算法通过计算误差能量函数,生成具有最小平均误差能量的视差图,并结合可靠度筛选和深度图生成技术,实现了对场景三维几何信息的重构。论文详细描述了算法的实现步骤,包括误差能量计算、视差图增强、深度图生成及3D显示过程,并通过实验验证了该方法的有效性。
完整源码链接 https://github.com/LamyaLi/cvLab
文章目录
一、 立体匹配的研究背景及意义
二、 立体匹配算法的基本实现思想
误差度量模型被定义为评估系统性能的关键指标,其计算公式基于预测值与真实值之间的差异。
2、基于最小平均误差能量的视差图
3、计算可靠度,生成具有可靠视差的视差图
4、由视差图生成深度图
三、 实现步骤与结果展示
1、计算误差能量,生成具有最小平均误差能量的视差图
2、计算可靠度,生成可靠视差的视差图
3、计算深度图
4、3D显示深度图
一、 立体匹配的研究背景及意义
在计算机视觉领域,立体视觉被视为一个关键课题。其主要目标是恢复场景的三维几何信息。研究立体视觉具有重要的应用价值,其应用领域涵盖移动机器人的自主导航系统、航空遥感测量以及工业自动化系统等多个方面。
立体视觉的一种研究方法,通过多幅图像恢复三维信息,属于被动型的方法。根据获取图像的方式的不同,可以划分为普通立体视觉和通常称为光流(optical flow)的两大类。普通立体视觉研究的对象是两台摄像机同时摄取的两张图像,而光流法中研究的是同一台摄像机沿任意运动轨迹连续拍摄的多张或更多图像。前者可被视为后者的特例,它们均具有相同的几何构型,研究方法也存在共同点。双目立体视觉是其中的一个特例。
其中,立体匹配是立体视觉系统的关键部分,是建立图像间的对应关系并计算视差信息的过程,具有重要意义。立体匹配主要包含两类算法:基于特征的算法和基于深度学习的算法。
(1) 基于灰度的算法 (intensity based),
(2) 基于特征的算法 (feature based)。
二、 立体匹配算法的基本实现思想
本文所采用的立体匹配算法思想源自《Obtaining Depth Maps From Color Images By Region Based Stereo Matching Algorithms》。该算法属于基于灰度的匹配算法,是一种基于区域的相关性方法。在图像中,以一个点为中心选定一个区域(窗口),在另一幅图像中寻找与该区域相关系数最大的区域,将找到的区域的中心视为原来该区域中心的对应点。该算法对噪声高度敏感,因此需要配合去噪滤波器使用。
1、误差能量函数
选取匹配计算区域窗口大小是(m*n)
d是视差,我们需要先定一个视差搜寻范围如dmax=40
由于该算法对噪声敏感,进一步计算平均error energy
2、基于最小平均误差能量的视差图
选取error energy最小的d作为视差图中(i,j)点的d,得到视差图
3、计算可靠度,生成具有可靠视差的视差图
前两步得到的视差图是有噪声的,可以先用中值滤波处理一遍。
定一个阈值ve,将error energy低于它的筛掉:
alpha是系数,系数越低,可靠度越高,但是去噪效果越不好。
其中sd是,不是ne的数量
4、由视差图生成深度图
根据这个三角关系,由视差图计算深度图,
三、 实现步骤与结果展示
左相机图
右相机图
1、计算误差能量,生成具有最小平均误差能量的视差图
for d in range(dmax):
##先计算 e (i,j,d)
for i in range(size1):
for j in range(size2):
sum =0
for m in range(window_size):
for n in range(window_size):
for k in range(3):
x=min(size1-1,i+m)
y=min(size2-1,j+n)
square_diff=(int(left[x][min(y+d,size2-1)][k])-int(right[x][y][k]))**2
sum=sum+square_diff
e[i][j]=sum/(3window_sizewindow_size)
##再计算e_avg(i,j,d)
for i in range(size1):
for j in range(size2):
e_temp = 0
for m in range(window_size):
for n in range(window_size):
x = min(size1-1, i + m)
y = min(size2-1, j + n)
e_temp=e_temp+e[x][y]
e_temp=e_temp/(window_size*window_size)
if e_temp
e_avg[i,j]=e_temp
disparity[i,j]=d
对视差图增强对比度显示(右边是增强对比度的):
#######增强对比度显示
temp=cv2.imread('disparity_base.png')
gray = cv2.cvtColor(temp, cv2.COLOR_RGB2GRAY) # 需要将输入图像转换为单通道灰度图像才能进行OpenCV的直方图均衡化。
dst = cv2.equalizeHist(gray)
cv2.imwrite('disparity_base_enhanced.png', dst)
temp2=cv2.imread('disparity_base_enhanced.png')
cv2.imshow('视差图(原图->对比度增强显示)', np.hstack([temp,temp2]))
cv2.waitKey()
cv2.destroyAllWindows()
2、计算可靠度,生成可靠视差的视差图
观察到结果图后,存在较多噪声点,不可靠的视差数量较多,因此这一步骤至关重要。
########################################用中值滤波处理视差图
cv2.medianBlur(disparity,3)
##########################################计算具有可靠视差的视差图
ve=alpha*e_avg.mean()
count_not_ne=0
sum_e=0
for i in range(size1):
for j in range(size2):
if e_avg[i][j]>ve:
######定ne
disparity[i][j]=0
else:
sum_e=sum_e+e_avg[i][j]
count_not_ne=count_not_ne+1
reliability=float(count_not_ne)**(-1)*sum_e
print("!!!!!!!!可靠度:",reliability)
3、计算深度图
其中将视差小于5的视为噪声处理
epth=np.ones_like(disparity,dtype=np.uint8)
for i in range(size1):
for j in range(size2):
if disparity[i][j]<5: ##噪音
depth[i][j]=0
else:
depth[i][j]=f*T//disparity[i][j]
cv2.medianBlur(depth,3)
4、3D显示深度图
X=range(size1)
Y=range(size2)
Z=depth
xx, yy=np.meshgrid(X, Y)#网格化坐标
X, Y=xx.ravel(), yy.ravel()#矩阵扁平化
bottom=np.zeros_like(X)#设置柱状图的底端位值
Z=Z.ravel()#扁平化矩阵
width=height=1#每一个柱子的长和宽
fig=plt.figure()
ax=fig.gca(projection='3d')#三维坐标轴
ax.bar3d(X, Y, bottom, width, height, Z, shade=True)#
#坐标轴设置
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z(depth)')
plt.show()
.gca(projection=‘3d’)#三维坐标轴
ax.bar3d(X, Y, bottom, width, height, Z, shade=True)#
#坐标轴设置
ax.set_xlabel(‘X’)
ax.set_ylabel(‘Y’)
ax.set_zlabel(‘Z(depth)’)
plt.show()
``
