赞
踩
视差图:以左视图视差图为例,在像素位置p的视差值等于该像素在右图上的匹配点的列坐标减去其在左图上的列坐标
视差图和深度图:
z
=
f
b
d
z = \frac{fb}{d}
z=dfb
其中
d
d
d 是视差,
f
f
f 是焦距,
b
b
b 是基线长度
所以,视差越大 ——> 深度越小
原理:是在给定窗口大小的情况下,对左图像和右图像的对应窗口进行比较,计算它们之间的绝对差的总和,从而确定最佳匹配的视差
SAD:Sum of Absolute Differences 即差的绝对值和
S
A
D
(
x
,
y
,
d
)
=
∣
w
L
(
x
,
y
)
−
w
R
(
x
−
d
,
y
)
∣
SAD(x,y,d) = |w_L(x, y) - w_R(x-d, y)|
SAD(x,y,d)=∣wL(x,y)−wR(x−d,y)∣
大致流程:
对左图像和右图像分别进行零填充以适应窗口的边界
为在计算这些像素的视差时,窗口可能会超出图像的范围
对于左图像的每个像素,依次遍历整个图像
对于每个像素,以其为中心取窗口大小的区域,并在右图像中搜索匹配窗口
# 一定是减去d,因为右边图像是左边图像向右平移d个像素
window_right = image_right[y:y + window_size, x - d:x - d + window_size]
设置一个
max_disparity
来限制搜索范围
计算左图像窗口和右图像匹配窗口的绝对差的总和,即SAD值
now_sad = np.sum(np.abs(window_left - window_right))
找到最小的SAD值,将对应的视差 d
保存到该像素位置
代码实现:
def sad(image_left, image_right, window_size=3, max_disparity=50): D = np.zeros_like(image_left) height = image_left.shape[0] width = image_left.shape[1] # 零填充 padding = window_size // 2 image_left = add_padding(image_left, padding).astype(np.float32) image_right = add_padding(image_right, padding).astype(np.float32) for y in range(height): for x in range(width): # 左边图像的窗口 window_left = image_left[y:y + window_size, x:x + window_size] best_disparity = 0 min_sad = float('inf') for d in range(max_disparity): if x - d < 0: continue # 一定是减去d,因为右边图像是左边图像向右平移d个像素 window_right = image_right[y:y + window_size, x - d:x - d + window_size] now_sad = np.sum(np.abs(window_left - window_right)) if now_sad < min_sad: min_sad = now_sad best_disparity = d # 保存SAD D[y, x] = best_disparity return D # 返回视差图
传统方法很慢,卷积方法避免了的嵌套循环,效率比起传统方法高了很多
利用图像卷积的思想,通过对每个候选视差值计算绝对差图像,并将其与一个均值滤波器进行卷积操作来实现视差图的计算
具体步骤如下:
对于每个候选的视差值,计算两幅图像在水平方向上的绝对差
img_diff = np.abs(image_left - right_shifted)
将计算得到的绝对差图像与一个均值滤波器进行卷积操作。均值滤波器的大小应与窗口大小相匹配,用于平滑绝对差图像,从而减少噪声和不稳定性
# 平滑均值滤波卷积核
kernel = np.ones((window_size, window_size)) / (window_size ** 2)
# 通过卷积运算,可以计算出每个像素邻域的总差异,也就是SAD值
img_sad = convolve(img_diff, kernel, mode='same')
卷积的作用:
- 平滑处理:卷积可以用来对图像进行平滑处理,也就是降噪。当卷积核是一个均值滤波器,就可以用于计算图像中每个像素的邻域的平均值。这样可以减少图像中的随机噪声,使图像变得更加平滑
- 计算局部差异:在计算左图和右图之间的 SAD 值时,需要对每个像素的邻域进行操作。这可以通过卷积来实现。卷积结果中的每个像素值表示了对应的像素邻域在左图和右图之间的差异程度
对于每个像素,选择具有最小卷积结果的视差值作为最终的视差值
代码实现:
def sad_convolve(image_left, image_right, window_size=3, max_disparity=50): # 零填充 padding = window_size // 2 image_left = add_padding(image_left, padding).astype(np.float32) image_right = add_padding(image_right, padding).astype(np.float32) SAD = np.zeros((image_left.shape[0], image_left.shape[1], max_disparity + 1)) # 卷积核 kernel = np.ones((window_size, window_size)) / (window_size ** 2) # 范围很重要,要覆盖0和max_disparity才行 for d in range(0, max_disparity才行 + 1): if d == 0: right_shifted = image_right else: right_shifted = np.zeros_like(image_right) right_shifted[:, d:] = image_right[:, :-d] img_diff = np.abs(image_left - right_shifted) # 通过卷积运算,可以计算出每个像素邻域的总差异,也就是SAD值 img_sad = convolve(img_diff, kernel, mode='same') SAD[:, :, d] = img_sad D = np.argmin(SAD, axis=2) # 选出算出最小SAD的视差值 return D
块匹配方法在处理时存在一些限制,主要包括以下几点:
局部窗口匹配:块匹配方法通常只考虑局部窗口内的像素信息进行匹配,而对于同质区域,局部窗口内的像素可能非常相似,导致匹配困难
窗口大小选择:选择合适的窗口大小对于块匹配的性能至关重要。
窗口大小 | 结果 |
---|---|
3 | |
7 | |
15 |
Siamese神经网络由两个相同的子网络组成,这两个子网络共享相同的参数(权重和偏置)。无论输入是什么,它们都会通过相同的网络结构进行处理
其有两种结构:
余弦相似度 (Cosine Similarity):
学习相似性 (Learned Similarity):
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。