Segment-Based Stereo Matching Using Belief Propagation and a Self-Adapting Dissimilarity Measure这篇论文为了读懂都花了我很多时间,虽然现在实现出来了,但是其中必然还有误解的地方。结果也有偏差,参数太多,调得我非常伤心。。。
论文的第一部分是图像分块,这部分是有代码的,mean shift的实现由Edge Detection and Image SegmentatiON (EDISON) System中的代码提供。起初我设置了加速segmentation,生成的结果很不稳定,大概是算法为了加速,先检测内存中的区块是不是之前segment的结果,如果是就直接拿来用。。。但这样有误差,对最终的结果影响也很大,后来我就改成NO SPEED UP了。
第二部分是局部匹配,这个在http://vision.middlebury.edu/stereo/中有给出代码,但与论文中的不太一样。论文采用自适应的方法,结合了SAD和梯度。
论文中的SAD里面,光强的差并没有加绝对值,后来无脑写完了代码一看结果不对才意识到,不知道是因为疏忽还是因为论文觉得SAD这么直观的名字不用再强调那么一个绝对值了。另外,求出的值被我除以了对应的窗口大小,从另一篇用差不多方法但是优化用的是GC的论文里看到的。感觉3×3的窗口并不适合于所有的情况,对于纹理很少的图像,应该采用更大的窗口吧,不过这里我也没有再改。
是在(x,y)处的3*3的包围窗口,是不带最左一列的包围窗口,是不带最下一行的包围窗口。是向右的forward gradient,是向下的forward gradient。彩色图像在每个通道单独计算,然后求和。
ω是最优权值,由最大化可靠对应像素的数量来决定,可靠像素是通过WTA和cross check来过滤的。
CrossCheck: 令匹配图像中的点(x',y'),对应源图像(x,y)。令d’(x’,y’)表示匹配图像像素(x’,y’)的初始disparity。则如果d(x,y)不等于d’(x’,y’),认为像素(x,y)是噪点。
WTA: 对每个(x,y),选择对应的C(x,y,d)最小的那个d,赋值给d(x,y)
这里论文的描述不是很确切,我并没有看懂w是怎么求出来的。只能推断出w并不是一个函数,而仅仅是一个数值(除非确实是w(x,y)只是论文不严谨)。鉴于WTA的处理过程是根据C(x,y,d)求出d(x,y),而cross check是根据d(x,y)和d'(x,y)来判断是否匹配的,因此除非用迭代优化的方法,不然如何从这两个后续的步骤中求出第一步local match里的w。不过从结果图看,我的噪点也确实多了点。。。。而且不管怎么看,都是SAD的方法噪点多。
4.3 修改了cross check方法之后,结果好了很多。之前是直接根据d(x,y)中取出的d值,加上x,然后对比d(x,y)与d'(x+d,y)的差异。但这样对d'很不公平啊= =。后来参考了一个matlab中的cross check算法,首先将右边图像根据它的d'(x,y),将每个像素移动成左边图像的格局得到d"(x,y),然后直接对比d(x,y)与d"(x,y)。
这一步还写道根据可靠对应来求得信噪率,然后对不相似性测量进行标准化,从而得到一个合适的截断阀值。这里并没有看明白如何去标准化,所以暂时没有实现。
大致伪代码如下:
void StereoMatch::LocalMatching()
{
计算两幅图的灰度图
根据灰度图计算梯度图
计算C(x,y,d),左图为引用图,右图为目标图
WinnerTakeAll : C(x,y,d)
计算C’(x,y,d),右图为引用图,左图为目标图
WinnerTakeAll : C’(x,y,d),
CrossCheck
}
CrossCheck和WTA的代码都很直观,计算C(x,y,d)也比较简单。
本文原创,转载请注明出处