窗口代价计算视差及NCC视差匹配实现

窗口代价计算视差及NCC视差匹配实现

1. 窗口代价计算视差的原理

立体匹配算法是计算机视觉中的一个难点和热点,一般的步骤是:

A、匹配代价计算

匹配代价计算是整个立体匹配算法的基础,实际是对不同视差下进行灰度相似性测量。常见的方法有灰度差的平方SD(squared intensity differences),灰度差的绝对值AD(absolute intensity differences)等。另外,在求原始匹配代价时可以设定一个上限值,来减弱叠加过程中的误匹配的影响。

B、 匹配代价叠加

一般来说,全局算法基于原始匹配代价进行后续算法计算。而区域算法则需要通过窗口叠加来增强匹配代价的可靠性。

C、 视差获取

对于区域算法来说,在完成匹配代价的叠加以后,视差的获取就很容易了,只需在一定范围内选取叠加匹配代价最优的点(SAD和SSD取最小值,NCC取最大值)作为对应匹配点,如胜者为王算法WTA(Winner-take-all)。而全局算法则直接对原始匹配代价进行处理,一般会先给出一个能量评价函数,然后通过不同的优化算法来求得能量的最小值,同时每个点的视差值也就计算出来了。

D、视差细化(亚像素级)

大多数立体匹配算法计算出来的视差都是一些离散的特定整数值,可满足一般应用的精度要求。但在一些精度要求比较高的场合,如精确的三维重构中,就需要在初始视差获取后采用一些措施对视差进行细化,如匹配代价的曲线拟合、图像滤波、图像分割等。亚像素级的处理就是涉及到BMState参数设置后后续参数的设置了。

2. NCC 视差匹配方法

局部的方法三种(计算匹配代价):
SAD(Sum of Absolute Differences):绝对差值的和
SSD(Sum of Squared Differences):差值平方的和
NCC(Normalized Cross Correlation):图像的相关性

原理简述

其实视差的求取关键在于找到对应的x与x’,则问题转换为如何找到左图中某点在右图中的对应点?以图像点x为例,在左图选取一个以x点为中心的特定大小的矩阵块,然后在右图中遍历,选取同样大小的矩阵块使得匹配代价最小,这时矩阵的中心点也就是右图中对应的x’点所在的位置。匹配代价的计算是针对矩阵中对应元素分别操作的,每个元素间的误差有两种定义方式,一种是用绝对差值,一种是用差值的平方,然后要将矩阵中所有元素误差加和,这样寻找最佳匹配点的方法分别叫做SAD和SSD。

因为是对矩阵中对应元素操作,既可以按行列遍历操作求解(即下面每种方法给出的第一种代码形式),也可以直接借助矩阵操作函数像absdiff、sum、multiply等进行整体运算。(即每种方法的第二种代码形式)。

NCC计算图像匹配区域的互相关性,与上面两种的计算方法不同

NCC原理

对于原始的图像内任意一个像素点(px,py)构建一个n×n的邻域作为匹配窗口。然后对于目标相素位置(px+d,py)同样构建一个n×nn×n大小的匹配窗口,对两个窗口进行相似度度量,注意这里的d有一个取值范围。对于两幅图像来说,在进行NCC计算之前要对图像处理,也就是将两帧图像校正到水平位置,即光心处于同一水平线上,此时极线是水平的,否则匹配过程只能在倾斜的极线方向上完成,这将消耗更多的计算资源。
在这里插入图片描述
其中NCC(p,d)得到的值得范围将在[−1,1]之间。
Wp为之前提到的匹配窗口。
I1(x,y)为原始图像的像素值。
I1¯¯¯(px,py)为原始窗口内像素的均值。
I2(x+d,y)为原始图像在目标图像上对应点位置在x方向上偏移d后的像素值。
I2¯¯¯(px+d,py)为目标图像匹配窗口像素均值。
若NCC=−1,则表示两个匹配窗口完全不相关,相反,若NCC=1NCC = 1NCC=1时,表示两个匹配窗口相关程度非常高。

匹配流程

采集图像:
通过标定好的双目相机采集图像,当然也可以用两个单目相机来组合成双目相机。
极线校正:
校正的目的是使两帧图像极线处于水平方向,或者说是使两帧图像的光心处于同一水平线上。通过校正极线可以方便后续NCC操作。
由标定得到的内参中畸变信息中可以对图像去除畸变。
通过校正函数校正以后得到相机的矫正变换R和新的投影矩阵P,接下来是要对左右视图进行去畸变,并得到重映射矩阵。
特征匹配:
这里便是我们利用NCC做匹配的步骤啦,匹配方法如上所述,右视图中与左视图待测像素同一水平线上相关性最高的即为最优匹配。完成匹配后,我们需要记录其视差d,即待测像素水平方向xl与匹配像素水平方向xr之间的差值d=xr−xl ,最终我们可以得到一个与原始图像尺寸相同的视差D。
深度恢复:
通过上述匹配结果得到的视差图D,我们可以很简单的利用相似三角形反推出以左视图为参考系的深度图。计算原理如下图所示:
在这里插入图片描述
如图,Tx为双目相机基线,f为相机焦距,这些可以通过相机标定步骤得到。而xr−xl就是视差d。

通过公式z=f×Tx/d可以很简单地得到以左视图为参考系的深度图了。

代码实现

即给定左右两张视图,根据NCC计算视差图,代码如下

import numpy as np
import cv2
import math

im1 = 'im2.ppm'
im2 = 'im6.ppm'
img1 = cv2.imread(im1, cv2.CV_8UC1)
img2 = cv2.imread(im2, cv2.CV_8UC1)
rows, cols = img1.shape
print(img1.shape)
#用3*3卷积核做均值滤波

def NCC(img1,img2,avg_img1,avg_img2,disparity,NCC_value,deeps, threshold,max_d, min_rows, max_rows):
    #设立阈值
    ncc_value = threshold
    if min_rows == 0:
        min_rows += 1
    for i in range(3, max_rows - 3):
        for j in range(3, cols-3):
            if j < cols - max_d-3:
                max_d1 = max_d
            else:
                max_d1 = cols - j - 3
            for d in range(4, max_d1):#减一防止越界
       
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值