在对BT算法说明前,先对AD(Absolute differences)算法进行简单说明。
如上图所示, I R ( x , y ) I_R(x,y) IR(x,y)、 I T ( x , y ) I_T(x,y) IT(x,y)分别表示左图和右图中的像素 ( x , y ) (x,y) (x,y)处的值,那么左图中像素 I R ( x , y ) I_R(x,y) IR(x,y)与右图中视差为 d d d的像素的AD代价值如下式所示:
c ( x , y , d ) = ∣ I R ( x , y ) − I T ( x + d , y ) ∣ c(x,y,d)=|I_R(x,y)-I_T(x+d,y)| c(x,y,d)=∣IR(x,y)−IT(x+d,y)∣
BT的代价也是像素灰度值差值的绝对值,不同之处在于BT利用了亚像素的灰度信息。
如图所示,首先计算左图中像素 ( x R − 0.5 , y ) (x_R -0.5,y) (xR−0.5,y)和 ( x R + 0.5 , y ) (x_R+0.5 ,y) (xR+0.5,y)之间亚像素位置 ( x R + x , y ) (x_R+x,y) (xR+x,y)的灰度值 I R ~ ( x R , y ) \widetilde{I_R}(x_R,y) IR (xR,y),然后计算右图中像素 ( x R + d − 0.5 , y ) (x_R +d-0.5,y) (xR+d−0.5,y)和 ( x R + d + 0.5 , y ) (x_R +d+0.5,y) (xR+d+0.5,y)之间亚像素位置 ( x R + d + x , y ) (x_R+d+x,y) (xR+d+x,y)的灰度值 I T ~ ( x R + d , y ) \widetilde{I_T}(x_R+d,y) IT (xR+d,y)。
分别计算两个代价:
c o s 1 = min x R − 1 2 ≤ x R + 1 2 ∣ I R ( x R , y ) − I T ~ ( x R + d , y ) ∣ cos_1=\min_{x_R-\frac{1}{2}\le x_R+\frac{1}{2} }|I_R(x_R,y)-\widetilde{I_T}(x_R+d,y)| cos1=xR−21≤xR+21min∣IR(xR,y)−IT (xR+d,y)∣ c o s 2 = min x R − 1 2 ≤ x R + 1 2 ∣ I T ( x R + d , y ) − I R ~ ( x R , y ) ∣ cos_2=\min_{x_R-\frac{1}{2}\le x_R+\frac{1}{2} }|I_T(x_R+d,y)-\widetilde{I_R}(x_R,y)| cos2=xR−21≤xR+21min∣IT(xR+d,y)−IR (xR,y)∣最终的代价为两个代价的最小值:
c o s = m i n ( c o s 1 , c o s 2 ) cos = min(cos_1,cos_2) cos=min(cos1,cos2)
注意:Opencv源码中,并没有计算太多亚像素的灰度值,只是取了两个像素中间点的亚像素的灰度值。
for( int d = minD; d < maxD; d++ )
{
int v = prow2[width-x-1 + d];// 之前右图是逆序存储,现在需要逆序取出,并加上视差值
int v0 = buffer[width-x-1 + d];// 最小值
int v1 = buffer[width-x-1 + d + width2];// 最大值
int c0 = std::max(0, u - v1); c0 = std::max(c0, v0 - u);
int c1 = std::max(0, v - u1); c1 = std::max(c1, u0 - v);
// cost计算。与原论文不同的是,opencv的B.T. metrics包含了两个部分,
// 一部分为prow1和prow2第一行所存储的左右图的sobel滤波结果的B.T. metrics,
// 一部分为prow1和prow2第二行所存储的左右图的灰度值的B.T. metrics
cost[x*D + d] = (CostType)(cost[x*D+d] + (std::min(c0, c1) >> diff_scale));
}