• 模块类图结构
  • BM(Block Matching)
    • 1. 参考资料
    • 2. 主要公式和概念
    • 3. 算法流程
    • 4. 注意事项
  • SGBM(Semi-Global Block Matching)
    • 1. 参考资料
    • 2. 主要公式和概念
    • 3. 算法流程
    • 4. 注意事项
  • 重要API参数解析
    • 1. StereoBinaryBM
    • 2. StereoBinarySGBM
  • 一些使用该模块时的注意事项
  • 运行效果截图

模块类图结构

1. StereoMatcher 类为该模块顶级父类,为一抽象类,定义了StereoBinary*子类的一些公共接口

2. StereoBinaryBM 和 StereoBinarySGBM为StereoMatcher类的两个派生子类, 分别实现了基于BM(Block Matching) 和 SGM(Semi-Global Matching)的立体匹配算法.

BM(Block Matching)

1. 参考资料

(1) Small Vision Systems: Hardware and Implementation 1997

(2) Weighted Semi-Global Matching and Center-Symmetric Census Transform for Robust Driver Assistance 2013

(3) Sum of Absolute Differences algorithm in stereo correspondence problem for stereo matching in computer vision application

2. 主要公式和概念

(0) 一些假设:

​ 块匹配假设在像素的局部区域, 所有像素具有同一视差值.

(1) Census Transformation(CT)变换: 一种将像素值变为Binary String 的变换. 通过将中心像素值与邻域内像素值比较(此处以8邻域为例), 大于中心像素值的置0(1), 反之置1(0). 公式如下:

LBPN(x,y)=∑i=0N−1s(ni−nc)2i>(1)(1)LBPN(x,y)=∑i=0N−1s(ni−nc)2i>

LBP_{N}(x, y) = \sum_{i = 0}^{N-1} s(n_i - n_c)2^i \tag{1} >

s(x)={10x≥0x<0>>s(x)={1x≥00x<0>>

s(x) = \begin{cases} 1 &x \ge 0 \\0 & x \end{cases} >

(2) 计算对应像素点间不同视差值下的汉明距离:

h(x,y,d)=HammingDistance(LBPL(x,y),LBPR(x−d,y))>(2a)(2a)h(x,y,d)=HammingDistance(LBPL(x,y),LBPR(x−d,y))>

h(x, y, d) = HammingDistance(LBP_L(x, y), LBP_R(x - d, y)) \tag{2a} >
Note: OpenCV的hammingDistanceBlockMatching() 函数返回的汉明距离图的内存组织形式如下:

Size(hammingDistance)=H×(W∗numDisparities)>(2b)(2b)Size(hammingDistance)=H×(W∗numDisparities)>

Size(hammingDistance) = H \times (W * numDisparities) \tag{2b} >
​ 其中每一行内容如下(以第 ii​i​ 行为例, n=numDisparitiesn=numDisparities​n = numDisparities​ ):

P(0, i) P(1, i) P(w, i)
h(0,i,0)h(0,i,0)h_{(0, i, 0)}, h(0,i,1)h(0,i,1)h_{(0, i, 1)}, …, h(0,i,n)h(0,i,n)h_{(0, i, n)} h(1,i,0)h(1,i,0)h_{(1, i, 0)}, h(1,i,1)h(1,i,1)h_{(1, i, 1)}), …, h(1,i,n)h(1,i,n)h_{(1, i, n)} h(w−1,i,0)h(w−1,i,0)h_{(w-1, i, 0)}, h(w−1,i,1)h(w−1,i,1)h_{(w-1, i, 1)}, …, h(w−1,i,n)h(w−1,i,n)h_{(w-1, i, n)}

(3) 块代价聚集(Block Cost Aggregate)

​ OpenCV实现中,分两步实现块代价聚集.

​ (i) 计算代价累计图

​ 代价的水平积累:

c′(x,y,d)=h(x−1,y−1,d)+c′(x−1,y,d)>(3.1a)(3.1a)c(x,y,d)′=h(x−1,y−1,d)+c(x−1,y,d)′>

c_{(x, y, d)}^{'} = h_{(x-1, y-1, d)} + c_{(x-1, y, d)}^{'} \tag{3.1a} >
​ 代价的垂直积累:

c(x,y,d)=c′(x,y,d)+c′(x,y−1,d)>(3.1b)(3.1b)c(x,y,d)=c(x,y,d)′+c(x,y−1,d)′>

c_{(x, y, d)} = c_{(x, y, d)}^{'} + c_{(x, y-1, d)}^{'} \tag{3.1b} >
​ (ii) 根据代价累计图计算指定窗内的块聚集代价

C(x,y,d)=c(x−w,y−w,d)+c(x+w,y+w,d)−c(x−w,y+w,d)−c(x+w,y−w,d)>(3.2)(3.2)C(x,y,d)=c(x−w,y−w,d)+c(x+w,y+w,d)−c(x−w,y+w,d)−c(x+w,y−w,d)>

C_{(x, y,d)} = c_{(x-w, y-w, d)} + c_{(x+w, y+w, d)} - c_{(x-w, y+w, d)} - c_{(x+w, y-w, d)} \tag{3.2} >
其中 w=(windowSize/2)w=(windowSize/2)w = (windowSize / 2) windowSizewindowSizewindowSize 必须为奇数. 上面两步的操作实际上就是求以某一点为中心的一个局部窗内的像素点的汉明距离的和.

​ (4) 根据块聚集代价图计算视差图
  (i) 在上一步得到的C(x,y,d)C(x,y,d)C_{(x, y, d)} 图中, 在每一个像素处,假设存在一个以像素p(x,y)p(x,y)p(x, y) 为横轴,以视差ddd 为纵轴的局部坐标系Coor(p,d)" role="presentation">Coor(p,d)Coor(p,d)Coor_{(p, d)} :
首先在坐标平面Coor(p,d)Coor(p,d)Coor_{(p, d)} 内原点处,沿垂直方向搜索一点(0,lr)(0,lr)(0, lr) 使得该点的C(x,y,d)C(x,y,d)C_{(x, y, d)} 值最小且满足confidence check条件(其中min∗min∗min* 表示第几小):

lr={min3(C(x,y,d3))min1(C(x,y,d1))≤CONFIDENCE,−1,d1others>(4.1a)(4.1a)lr={min3(C(x,y,d3))min1(C(x,y,d1))≤CONFIDENCE,d1−1,others>

lr = \begin{cases} \frac{min3(C_{(x, y, d_3)})}{min1(C_{(x, y, d_1)})} \le CONFIDENCE, &d_1 \\-1, &others\end{cases} \tag{4.1a} >
当lr≠−1lr≠−1lr \ne -1 时, 再次在坐标平面Coor(p,d)Coor(p,d)Coor_{(p, d)} 内的[p−lr,pnumDisparity−lr][p−lr,pnumDisparity−lr][p_{-lr}, p_{numDisparity-lr}] 区间内沿对角线搜索一点(p,v)(p,v)(p, v) 使得该点同样满足上述条件:

v={min3(C(x,y,d3))min1(C(x,y,d1))≤CONFIDENCE,−1,d1others>(4.1b)(4.1b)v={min3(C(x,y,d3))min1(C(x,y,d1))≤CONFIDENCE,d1−1,others>

v = \begin{cases} \frac{min3(C_{(x, y, d_3)})}{min1(C_{(x, y, d_1)})} \le CONFIDENCE, &d_1 \\-1, &others\end{cases} \tag{4.1b} >
  (ii) 得到lr,vlr,vlr, v 后, 对其进行差值,得到sub-pixel级别的结果p1,p2p1,p2p1, p2 , 如果p1,p2p1,p2p1, p2 差值在阈值范围内,则该像素点的视差值为p2∗scallingFactorp2∗scallingFactorp2*scallingFactor , 否则视差为0:

p1,p2p1,p2p1, p2 差值公式如下:

p′={12−14∗[(m3−m1m2−m1)2+m3−m1m2−m1]−1∗[12−14∗[(m3−m1m2−m1)2+m3−m1m2−m1]]m2>m3others>(4.2.a)(4.2.a)p′={12−14∗[(m3−m1m2−m1)2+m3−m1m2−m1]m2>m3−1∗[12−14∗[(m3−m1m2−m1)2+m3−m1m2−m1]]others>

p^{'} = \begin{cases}\frac12 - \frac14*[(\frac{m3-m1}{m2-m1})^2 + \frac{m3-m1}{m2-m1}] &m2 \gt m3 \\-1*[\frac12 - \frac14*[(\frac{m3-m1}{m2-m1})^2 + \frac{m3-m1}{m2-m1}]] &others \end{cases} \tag{4.2.a} >

p1=p′+v>(4.2.b)(4.2.b)p1=p′+v>

p1 = p^{'} + v \tag{4.2.b} >

p2=p′+lr>(4.2.c)(4.2.c)p2=p′+lr>

p2 = p^{'} + lr \tag{4.2.c} >

d={p2∗scallingFactor0|p1−p2|≤threshothers>(4.2.d)(4.2.d)d={p2∗scallingFactor|p1−p2|≤thresh0others>

d = \begin{cases}p2 * scallingFactor & |p1-p2| \le thresh \\0 &others\end{cases} \tag{4.2.d} >

Note: 计算p1,p2p1,p2p1, p2 时, p′p′p^{'} 计算公式中的m1,m2,m3m1,m2,m3m1, m2, m3 是不相同的.
(5) 后处理: 滤掉一些斑点区域(speckle)同时对于空洞区域进行插值处理.

CV_SPECKLE_REMOVAL_AVG_ALGORITHMd(x,y)={d(x,y)1n(∑nid(xi,yi))d(x,y)>0others>(5a)(5a)CV_SPECKLE_REMOVAL_AVG_ALGORITHMd(x,y)={d(x,y)d(x,y)>01n(∑ind(xi,yi))others>

CV\_SPECKLE\_REMOVAL\_AVG\_ALGORITHM \\d(x, y) = \begin{cases}d(x, y) &d(x, y) \gt 0 \\\frac1n(\sum_i^nd(x_i, y_i)) &others \end{cases} \tag{5a} >

CV_SPECKLE_REMOVAL_ALGORITHMd(x,y)={d(x,y)NEW_VALUEd(x,y)>0others>(5b)(5b)CV_SPECKLE_REMOVAL_ALGORITHMd(x,y)={d(x,y)d(x,y)>0NEW_VALUEothers>

CV\_SPECKLE\_REMOVAL\_ALGORITHM \\d(x, y) = \begin{cases}d(x, y) &d(x, y) \gt 0 \\NEW\_VALUE &others \end{cases} \tag{5b} >

3. 算法流程
Created with Raphaël 2.1.2开始CT变换->censusImageLeft,censusImageLeft 计算censusImageLeft,censusImageLeft两图中对应像素在不同视差值下的汉明距离图->hammingDistance计算块匹配的聚合代价->agregatedHammingLRCost计算视差图->disp0后处理->disparityMap结束
4. 注意事项

​ (1) 通过create() 创建BM算法对象时, numDisparities 参数必须能被16整除, blockSize 参数必须为奇数.

​ (2) 通过compute() 函数计算视差图时, 作为输入参数的左右两张图必须具有相同大小且图像类型都为CV_8UC1.


SGBM(Semi-Global Block Matching)

1. 参考资料

(1) Stereo Processing by Semi-Global Matching and Mutual Information 2008

(2) A Pixel Dissimilarity Measure That Is Insensitive to Image Sampling 1998

(3) Small Vision Systems: Hardware and Implementation 1997

2. 主要公式和概念

​ (0) 一些基本公式

MII1,I2=H1+H2−HI1,I2>(1)(1)MII1,I2=H1+H2−HI1,I2>

MI_{I_1, I_2} = H_1 + H_2 - H_{I_1, I_2} \tag{1} >

HI=−∫10PI(i)logPI(i)di>(2)(2)HI=−∫01PI(i)logPI(i)di>

H_I = -\int_0^1 P_I(i)logP_I(i)di \tag{2} >

HI1,I2=−∫10∫10PI1,I2(i1,i2)logPI1,I2(i1,i2)di1di2>(3)(3)HI1,I2=−∫01∫01PI1,I2(i1,i2)logPI1,I2(i1,i2)di1di2>

H_{I_1, I_2} = -\int_0^1\int_0^1 P_{I_1, I_2}(i_1, i_2) logP_{I_1, I_2}(i_1, i_2)di_1di_2 \tag{3} >

HI1,I2=∑phI1,I2(I1p,I2p)>(4)(4)HI1,I2=∑phI1,I2(I1p,I2p)>

H_{I_1, I_2} = \sum_p h_{I_1, I_2}(I_{1p}, I_{2p}) \tag{4} >

hI1,I2(i,k)=−1nlog(PI1,I2(i,k)⊗g(i,k))⊗g(i,k)>(5)(5)hI1,I2(i,k)=−1nlog(PI1,I2(i,k)⊗g(i,k))⊗g(i,k)>

h_{I_1, I_2}(i, k) = -\frac{1}{n} log(P_{I_1, I_2}(i, k) \otimes g(i, k)) \otimes g(i, k) \tag{5} >

PI1,I2(i,k)=1n∑pT[(i,k)==(I1p,I2p)]>(6)(6)PI1,I2(i,k)=1n∑pT[(i,k)==(I1p,I2p)]>

P_{I_1, I_2}(i, k) = \frac{1}{n} \sum_p T[(i, k) == (I_{1p}, I_{2p})] \tag{6} >

​ (1) Mutual Information(互信息):

参考:

​ 博客: 经典算法Semi-Global Matching(SGM) 之HMI计算

MI是一种基于熵定义的用于表示两幅图相关性的一个概念. 对于在Base Image 和 Match Image 中没有相互对应的像素点对的值I1,I2I1,I2I_1, I_2,对其熵的定义仿照联合熵进行定义:

HI=∑phI(Ip)>(1a)(1a)HI=∑phI(Ip)>

H_I = \sum_{p} h_I(I_p) \tag{1a} >

hI(i)=−1nlog(PI(i)⊗g(i))⊗g(i)>(1b)(1b)hI(i)=−1nlog(PI(i)⊗g(i))⊗g(i)>

h_I(i) = -\frac{1}{n} log(P_I(i) \otimes g(i)) \otimes g(i) \tag{1b} >

其中 g(i)g(i)g(i) 为 Gaussian 函数。

因此, MI 的最总定义如下:

MII1,I2=∑pmiIi,I2(I1p,I2p)>(1c)(1c)MII1,I2=∑pmiIi,I2(I1p,I2p)>

MI_{I_1, I_2} = \sum_{p} mi_{I_i, I_2}(I_{1_p}, I_{2_p}) \tag{1c} >

miIi,I2(i,k)=hI1(i)+hI2(k)−hI1,I2(i,k)>(1d)(1d)miIi,I2(i,k)=hI1(i)+hI2(k)−hI1,I2(i,k)>

mi_{I_i, I_2}(i, k) = h_{I_1}(i) + h_{I_2}(k) - h_{I_1, I_2}(i, k) \tag{1d} >

​ (2) 基于MI的代价函数(MI Matching Cost)CMICMIC_{MI} :

CMI(p,d)=−miIb,fD(Im)(Ibp,Imq)>(2a)(2a)CMI(p,d)=−miIb,fD(Im)(Ibp,Imq)>

C_{MI(p, d)} = -mi_{I_b, f_D(I_m)}(I_{bp}, I_{mq}) \tag{2a} >

q=ebm(p,d)>(2b)(2b)q=ebm(p,d)>

q = e_{bm}(p, d) \tag{2b} >

>ebm(p,d)=[px−d,py]T>(2c)(2c)>ebm(p,d)=[px−d,py]T>

>e_{bm}(p, d) = [p_x - d, p_y]^T \tag{2c} >

fD(Im)=D+Im>fD(Im)=D+Im>

f_D(I_m) = D + I_m >

其中 DDD 为视差图 D=Ib−Im" role="presentation">D=Ib−ImD=Ib−ImD = I_b - I_m

Note: 根据上述公式定义,可以看到,CMICMIC_{MI} 的计算需要事先知道视差图。这在实际应用中是不太可能满足的。作者在论文中提出了,首先对原图进行 116116\frac{1}{16} 的缩放,然后初始化一张随机的视差图,进行3次迭代计算后,再逐层向上放大,每层进行一次计算,直到和原图大小相同为止。另外,需要注意,为了保证误差不会逐层向上传播,较低分辨率的视差图只用于估计PPP ,而CMI" role="presentation">CMICMIC_{MI} 则用更高分辨率的视差图进行计算,其余的所有参数都从0开始计算. 上述公式中,(i,k)(i,k)(i, k) 分别代表 I1,I2I1,I2I_1, I_2 中像素点的值(pixel intensities)。PI(i)PI(i)P_I(i) 和 PI1.I2(i,k)PI1.I2(i,k)P_{I_1. I_2}(i, k) 表示值为 iii 的像素点和(i,k)" role="presentation">(i,k)(i,k)(i, k) 的像素点对出现的概率。

(3) 代价聚集(Cost Aggregation)

参考:

​ 博客: 经典算法Semi-Global Matching(SGM) 之动态规划

首先定义全局能量函数:

E(D)=∑p[C(p,Dp)+∑q∈Np(P1T[|Dp−Dq|=1])+∑q∈Np(P2T[|Dp−Dq|>1])]>(11)(11)E(D)=∑p[C(p,Dp)+∑q∈Np(P1T[|Dp−Dq|=1])+∑q∈Np(P2T[|Dp−Dq|>1])]>

E(D) = \sum_{p} [ C(p, D_p) + \sum_{q \in N_p}(P_1T[|D_p - D_q| = 1]) + \sum_{q \in N_p}(P_2T[|D_p - D_q| > 1]) ] \tag{11} >
​ 其中NpNpN_p 表示像素ppp 的邻域.P1,P2" role="presentation">P1,P2P1,P2P_1, P_2 是惩罚系数.较小的P1P1P_1 使得该能量函数对于斜面和曲面(slanted or curved surface) 具有一定的适应性, 较大的P2P2P_2 使得能量函数能尽量阻止不连续性视差的产生. 一般来说,在边缘处的视差不连续变换是正常的,因此可以将P2P2P_2 设置为一个与图像梯度相适应的值,即 P2=P′2|Ibp−Ibq|P2=P2′|Ibp−Ibq|P_2 = \frac{P_2^{'}}{|I_{bp} - I_{bq}|} .这样,对于处于边缘处的像素,即使是较大的视差变化,也能容忍.

​ 有了上述能量函数后,求解立体匹配的问题就变成了求解使能量函数E(D)E(D)E(D) 最小化的问题.而对于二维平面来说,求解该问题是一个NP完全问题. 如果将图像的每一行独立出来,则该问题转化为一个1D的优化问题,可以使用动态规划进行求解. 但是这样一来就会存在条纹效应(streaking). 因为这样只考虑了水平方向的约束,而对垂直方向的约束很弱甚至没有. 为了解决这个问题,作者在论文中提出了”aggregating matching costs in 1D from all directions equally”, 即对于每一个像素点,计算每一个方向上的一条代价最小路径的和,将之作为聚合后的代价值. 示意图如下:

首先递归定义每个方向上的最小代价:

Lr(p,d)=C(p,d)+min[Lr(p−r,d),Lr(p−r,d−1)+P1,Lr(p−r,d+1)+P1,mini[Lr(p−r,i)+P2]−minkLr(p−r,k)]>(3a)(3a)Lr(p,d)=C(p,d)+min[Lr(p−r,d),Lr(p−r,d−1)+P1,Lr(p−r,d+1)+P1,mini[Lr(p−r,i)+P2]−minkLr(p−r,k)]>

\begin{split}L_r(p, d) = C(p, d) + \min[ &L_r(p-r, d), \\&L_r(p-r, d-1) + P_1, \\&L_r(p-r, d+1) + P_1, \\&\min_i[L_r(p-r, i) + P_2] - \min_kL_r(p-r, k) ]\end{split} \tag{3a} >
则对于每个像素点,其聚合代价定义如下:

S(p,d)=∑rLr(p,d)>(3b)(3b)S(p,d)=∑rLr(p,d)>

S(p, d) = \sum_{r} L_r(p, d) \tag{3b} >

​ (4) 视差计算(Disparity Computation)

由(3)最小化聚合代价, 我们可以得到视差图 D=mindS[p,d]D=mindS[p,d]D = \min_dS[p, d] , 分别对左右两张图都进行上述计算,则有:

Dbp=mindS(bp,d)>(4a)(4a)Dbp=mindS(bp,d)>

D_{bp} = \min_dS(bp, d) \tag{4a} >

Dmp=mindS(np,d)>(4b)(4b)Dmp=mindS(np,d)>

D_{mp} = \min_dS(np, d) \tag{4b} >

然后进行视差一致性检验(disparity consistency check), 得到最终的视差图DpDpD_p:

Dp={DbpDinvalidif |Dbp−Dmq|≤disp12MaxDiffothers>(4c)(4c)Dp={Dbpif|Dbp−Dmq|≤disp12MaxDiffDinvalidothers>

D_p = \begin{cases}D_{bp} &if |D_{bp} - D_{mq}| \le disp12MaxDiff \\D_{invalid} &others\end{cases} \tag{4c} >

q=ebm(p,Dbp)>(4d)(4d)q=ebm(p,Dbp)>

q = e_{bm}(p, D_{bp}) \tag{4d} >

​ (5) Disparity Refinement

​ (i) Removal of Peaks: 对上一步得到的视差图,利用区域生长的, 取得不同的区域

Ci=∑p(|Dp−Di|≤speckleRange)>(5.1a)(5.1a)Ci=∑p(|Dp−Di|≤speckleRange)>

C_i = \sum_p(|D_{p} - D_i| \le speckleRange) \tag{5.1a} >
对得到的所有区域, 统计该区域的像素点的个数, 将之作为该区域的大小Size(Ci)=COUNT(Ci)Size(Ci)=COUNT(Ci)Size(C_i) = COUNT(C_i) , 如果区域大小小于某一阈值,则认为该区域为speckle, 将区域内视差值都标记为非法值:

Dp={DpDinvalidif Size(Ci)<speckleWindowSizeothers>Dp={DpifSize(Ci)<speckleWindowSizeDinvalidothers>

D_{p} = \begin{cases}D_{p} &if  Size(C_i) \lt speckleWindowSize \\D_{invalid} &others\end{cases} >
​ (5) Birchfield-Tomasi 代价函数根据块聚集代价图计算视差图

I−R=IR^(xR−12)=12(IR(xR)+IR(xR−1))>(4a)(4a)IR−=IR^(xR−12)=12(IR(xR)+IR(xR−1))>

I_R^- = \hat{I_R}(x_R - \frac12) = \frac12 (I_R(x_R) + I_R(x_R - 1)) \tag{4a} >

I+R=IR^(xR+12)=12(IR(xR)+IR(xR+1))>(4b)(4b)IR+=IR^(xR+12)=12(IR(xR)+IR(xR+1))>

I_R^+ = \hat{I_R}(x_R + \frac12) = \frac12 (I_R(x_R) + I_R(x_R + 1)) \tag{4b} >

Imin=min(I−R,I+R,IR(xr))>(4c)(4c)Imin=min(IR−,IR+,IR(xr))>

I_{min} = \min{(I_R^-, I_R^+, I_R(x_r))} \tag{4c} >

Imax=max(I−R,I+R,IR(xr))>(4d)(4d)Imax=max(IR−,IR+,IR(xr))>

I_{max} = \max{(I_R^-, I_R^+, I_R(x_r))} \tag{4d} >

d¯(xL,xR,IL,IR)=max(0,IL(xL)−Imax,Imin−IL(xL))>(4e)(4e)d¯(xL,xR,IL,IR)=max(0,IL(xL)−Imax,Imin−IL(xL))>

\bar{d}(x_L, x_R, I_L, I_R) = \max{(0, I_L(x_L) - I_{max}, I_{min} - I_L(x_L))} \tag{4e} >

对于另外一张图,具有类似的对称定义d¯(xR,xL,IL,IR)d¯(xR,xL,IL,IR)\bar{d}(x_R, x_L, I_L, I_R) .

3. 算法流程
Created with Raphaël 2.1.2开始CT变换->censusImageLeft,censusImageLeft 计算CT变换后两图中对应像素在不同视差值下的汉明距离图->hammingDistance根据SGM算法计算视差图->disp后处理->disparityMap结束
4. 注意事项

OpenCV中的SGBM算法与原始论文中的算法略有不同,主要体现在以下几个点(SGBM API文档):

​ (1) 算法中计算聚合代价(aggregation cost)时, 计算的是8个方向上的聚合代价,而实现中默认只计算5个方向, 可以通过在创建SGBM对象时通过设置mode = StereoSGBM::MODE_HH 来改变算法行为, 使之计算8个方向.

​ (2) 原始论文中使用的是单像素匹配, 实现使用的是块匹配(block match). 可以通过设置blockSize = 1 来将块匹配降级为单像素匹配.

​ (3) 原始论文使用互信息(mutual information)作为匹配的代价函数, 实现中使用一种更简单的, 在参考资料[2]中提出的Birchfield-Tomasi 代价函数.

​ (4) 实现了参考资料[3] 中使用的一些后处理方法, 提高算法结果.


重要API参数解析

1. StereoBinaryBM

(1) StereoBinaryBM::create()

    /**  @brief Creates StereoBM object @param numDisparities 视差值d的搜索范围. @param blockSize 进行块聚合代价计算时的块窗口大小.必须为奇数! */
static Ptr<cv::stereo::StereoBinaryBM> create(int numDisparities = 0,int blockSize = 9);
2. StereoBinarySGBM

(1) StereoBinarySGBM::create()64

    /** @brief Creates StereoSGBM object@param minDisparity 视差值的最小值. @param numDisparities Maximum disparity minus minimum disparity. @param blockSize 块匹配的窗口大小, 必须为奇数且应在[3,11]区间内取值. @param P1 公式(3a)中的P1. The first parameter controlling the disparity smoothness.This parameter is used for the case of slanted surfaces (not fronto parallel).@param P2 公式(3a)中的P2. The second parameter controlling the disparity smoothness.This parameter is used for "solving" the depth discontinuities problem. The larger the values are, the smoother the disparity is. P1 is the penalty on the disparity change by plus or minus 1 between neighborpixels. P2 is the penalty on the disparity change by more than 1 between neighbor @param disp12MaxDiff 在对视差值进行左右交叉验证时,允许对应像素点处出现的左右视差的最大差值. prefiltered image pixels. The algorithm first computes x-derivative at eachpixel and clips its Birchfield-Tomasi pixel cost function. @param uniquenessRatio Margin in percentage by which the best (minimum) computedcost function value should "win" the second best value to consider the foundmatch correct. Normally, a value within the 5-15 range is good enough. 对算法在边缘处的视差值具有较大影响,使用默认值即可.@param speckleWindowSize Maximum size of smooth disparity regions to consider their noise speckles and invalidate. Set it to 0 to disable speckle filtering.Otherwise, set it somewhere in the 50-200 range.@param speckleRange 计算区域大小时,判断两个点是否属于同一区域的差值阈值. Maximum disparityvariation within each connected component. If you do speckle filtering, set the parameter to a positive value, it will be implicitly multiplied by 16. Normally, 1 or 2 is good enough.@param mode Set it to StereoSGBM::MODE_HH to run the full-scale two-pass dynamicprogramming algorithm. It will consume O(W\*H\*numDisparities) bytes, whichis large for 640x480 stereo and huge for HD-size pictures. By default, it is set to false .*/
static Ptr<cv::stereo::StereoBinarySGBM> create(int minDisparity, int numDisparities, int blockSize,int P1 = 100,int P2 = 1000,int disp12MaxDiff = 1,int preFilterCap = 0, int uniquenessRatio = 5,int speckleWindowSize = 400,int speckleRange = 200,int mode = StereoBinarySGBM::MODE_SGBM);

一些使用该模块时的注意事项

  1. numDisparities 参数对于算法性能影响很大, 应尽量设得小一些, 单应能被16整除.
  2. blockSize 参数一般应设在[3, 11]内, 根据不同的CT变换核函数, 其范围略微有所不同.

运行效果截图

Input Image size: [384 x 288]
BM Costs: 47.3848 ms
SGBM Costs: 35.6961 ms
numDisparities: 64
blockSize: 9

输入左右视图:

左视图

右视图

真实视差图:

BM算法得到的视差图(归一化到0-255):

SGBM算法得到的视差图(归一化到0-255):


立体匹配(Stereo Matching)相关推荐

  1. python立体匹配误匹配率_立体匹配算法(Stereo Matching)及其在OpenCV中的应用

    模拟人的两只眼睛的Stereo相机最近变得很受欢迎.通过对stereo相机拍摄的左右两张图进行匹配找出视差图,可以还原物体的3D信息. 立体匹配(Stereo matching)的步骤如下: 1: 预 ...

  2. DSM: 域不变的立体匹配网络解析(Stereo Matching Networks)

    作者| flow 编辑| 3D视觉开发者社区 导语:本文是由来自牛津大学.百度研究院以及香港中文大学团队发表的论文,该团队提出了域不变的立体匹配网络方法,用于解决立体匹配网络中直接跨域泛化的问题.适合 ...

  3. Stereo Matching 立体匹配学习资料

    Middlebury Stereo Evaluation Camera Calibration and 3D Reconstruction OpenCV学习笔记(18)双目测距与三维重建的OpenCV ...

  4. Stereo Matching文献笔记之(六):浅谈置信度传播算法(Belief-Propagation)在立体匹配中的应用~

    这是我一个纠结过的问题,曾经反反复复的看相关的知识,Belief-Propagation是一个伴随着"马尔科夫随机场"提出的优化算法,我对优化算法情有独钟,一直觉得搞定了各种优化, ...

  5. 论文阅读《PatchMatch Stereo - Stereo Matching with Slanted Support Windows》(PMS-双目立体匹配)

    论文地址:PatchMatch Stereo - Stereo Matching with Slanted Support Windows 问题提出   局部匹配方法在计算匹配代价中是基于Fronto ...

  6. 立体匹配|Stereo Matching

    文章目录 背景概念 对极几何 视觉模型 基本流程 匹配代价计算 代价聚合 视差计算 视差优化 References 立体匹配也称 视差估计. 双目深度估计 输入:一对在统一时刻捕捉的,经过 极线校正 ...

  7. 论文阅读《On Building an Accurate Stereo Matching System on Graphics Hardware》(AD Census-双目立体匹配)

    论文地址:On Building an Accurate Stereo Matching System on Graphics Hardware 问题提出   基于SGM的方法速度快,但精度不高,基于 ...

  8. 基于Patachmatch的stereo matching笔记(一):《PatchMatch Stereo》

    Patchmatch Stereo 论文:PatchMatch Stereo - Stereo Matching with Slanted Support Windows(2011) Patchmat ...

  9. 基于Patachmatch的stereo matching笔记(二):《DeepPruner》

    DeepPruner 论文:DeepPruner: Learning Efficient Stereo Matching via Differentiable PatchMatch(2019) 1. ...

  10. OpenCV stereo matching 代码 matlab实现视差显示

    转载请注明出处:http://blog.csdn.net/wangyaninglm/article/details/44151213, 来自:shiter编写程序的艺术 基础知识 计算机视觉是一门研究 ...

最新文章

  1. Python工具 | 4个好用的开源 Python 下载器
  2. redux异步action_Redux数据状态管理
  3. 悲观锁和乐观锁_乐观锁和悲观锁 以及 乐观锁的一种实现方式-CAS
  4. Spring PropertyPlaceholderConfigurer Usage - 使用系统变量替换spring配置文件中的变量
  5. gitlab+keepalived
  6. Unity3D_07_日志、文本打印
  7. qt mysql读写_QT读写Sqlite数据库
  8. 查看git当前tag_同学,也该学着用Git了......
  9. ERROR 程序出错,错误原因:'bytes' object has no attribute 'read'
  10. Spring在多线程中bean的注入问题
  11. 苹果怎么删除通讯录联系人_苹果手机通讯录怎么恢复?这才是正确的打开方式!...
  12. 软件测试管理要素分析
  13. amd超频软件LINUX,cpu超频软件amd
  14. BBRv2 Cruise 阶段的 inflight 补偿
  15. 玩转微信|两种微信批量删除好友教程
  16. 开发谷歌浏览器翻译插件
  17. Git项目管理修改项目名称
  18. 阿里云 OSS 之图片处理
  19. odoo10 -- 请假模块
  20. 具有多个项目的可访问拖放

热门文章

  1. 构建WindowsPhone生态:梁念坚博士答记者问windowsphone
  2. 简信CRM:CRM科学服务体系,促进企业销售增长
  3. SLAM前端之ndt_omp使用
  4. 我的游戏开发收藏夹 (不定期更新)
  5. FIL最新行情,FIL预测能涨至750U是否过于夸大?会突破新高吗?
  6. 搜索推荐广告三者异同
  7. pg8168改mac命令_Realtek 8168网卡改MAC地址教程
  8. 独立站SaaS建站模式是什么
  9. 项目管理10大知识领域和47个过程的思维导图
  10. 使用python将windows下多种文件格式转换成PDF格式