立体匹配和其他图像处理方法不同,由于涉及到视差对应,在图像边缘往往出现参考图像在匹配图像上的对应像素超出匹配图像范围的情况,这时如果采取一刀切的办法容易出现图像边缘大量有用信息的丢失。于是,我们很自然地想到这样解决问题:
1、参考图像边缘导致对应像素超出匹配图像范围的视差应当直接丢弃,而从其他非超出图像范围的视差中取最优视差值。
2、在计算代价时,给超出图像范围的视差以很大的代价,然后无差别地从所有视差中取最优视差。
如上图所示,假设初始视差范围为[-10,9](虽然不是常态,但是有时算法原因导致首尾视差范围减除首尾视差,变为[-9,8])。假设已经计算了像素P在[-9,8]视差范围的所有代价,而disparity=-9和disparity=8时对应像素p'超出图像范围,这时我们需要丢弃-9和8,而在[-8,7]范围搜索最优视差值,具体代码如下所示:
int i,j,d;
float *tempdisp = new float[dispnum-2];
float tempf;
int tempi;
int t = 0;
for (i=0;i<height;i++)
{
for (j=0;j<width;j++)
{
int index = i*width+j;
int disparity_begin_temp = disparity_begin;
for (d=1,t=0;d<dispnum-1;d++)
{
if (j+d+disparity_begin>=0 && j+d+disparity_begin<width)
{
tempdisp[t] = aggcost[index*dispnum+d];
t++;
}
else if (j+d+disparity_begin < 0)
{
disparity_begin_temp++;
}
}
GetMin(tempdisp,t,&tempf,&tempi);
disparity[i*width+j] = tempi+disparity_begin_temp+1;
dispmap[i*width+j] = tempi+disparity_begin_temp-disparity_begin+1;
}
}
delete[] tempdisp;
其中,GetMin的函数实现如下:
void GetMin(float *val, int num, float *minval, int *index)
{
float mintemp = 999999.0f;
int tempindex;
for (int i=0;i<num;i++)
{
if (val[i]<mintemp)
{
mintemp = val[i];
tempindex = i;
}
}
*minval = mintemp;
*index = tempindex;
}
而常规的直接从所有视差范围选择最优视差的方法如下所示:
int i,j,d;
float *tempdisp = new float[dispnum-2];
float tempf;
int tempi;
int t = 0;
for (i=0;i<height;i++)
{
for (j=0;j<width;j++)
{
int index = i*width+j;
int disparity_begin_temp = disparity_begin;
for (d=1,t=0;d<dispnum-1;d++)
{
tempdisp[t] = aggcost[index*dispnum+d];
t++;
}
GetMin(tempdisp,t,&tempf,&tempi);
disparity[i*width+j] = tempi+disparity_begin_temp+1;
dispmap[i*width+j] = tempi+1;
}
}
delete[] tempdisp;
下面,我们通过实验对比这种方法的有效性:
由上图可以看出,虽然用本文方法确实补充了直接从所有视差中选择最优视差方法导致的图像边缘的视差信息丢失,但是其实很多结果是错误的!究其原因,是边缘图像的代价错误导致的,我们在计算costmatrix时,对于超出图像范围的代价值给了0,这样做不对!我们现在把它改为999,实验结果如下:
由上图可以看出,这时两种方法的处理结果几乎没有任何差别!
结论:
1、立体匹配中视差范围导致的边缘信息丢失应当主要通过代价惩罚来实现,即在计算costmatrix时,给超出参考图像范围的视差赋以很大的代价。如果匹配算法(如本文采用的SGM算法)中每个像素的代价互相不独立,那么这一处理方法不仅是充分条件也是必要条件!
2、在选择视差时,从所有视差范围中选择最优值或从非超出图像范围的视差中选择最优值存在差别,但是在考虑了上述1之后,差别几乎完全消除。
3、当然,最好的方法是结合两者,在考虑了1所述的代价惩罚之后,继续采用本文所述的缩小视差搜索范围的方法理论上仍然由于无差别的搜索方法,不仅是计算结果,而且GetMin计算耗时也会降低。