以下是osg官方原话(南水之源译)
osgstereomatch示例演示了如何在立体视觉视差图计算中使用GPU上的多个渲染通道和多个渲染目标。
以单遍和多遍方式实现一种简单算法,以显示执行速度的差异。
调用示例的参数:
osgstereomatch --left Images/dog_left_eye.jpg --right Images/dog_right_eye.jpg --min 0 --max 31 --window 9 osgstereomatch --left Images/dog_left_eye.jpg --right Images/dog_right_eye.jpg --min 0 --max 31 --window 9 --single
使用可从以下位置的Middlebury Stereo Vision页面获得的样本数据:
http://vision.middlebury.edu/stereo/
osgstereomatch --left tsukubaL.png --right tsukubaR.png --min 0 --max 15 --window 5 osgstereomatch --left tsukubaL.png --right tsukubaR.png --min 0 --max 15 --window 5 --single osgstereomatch --left teddyL.png --right teddyR.png --min 10 --max 57 --window 7
算法和实现细节:
该算法使用像素之间的绝对差之和(在文献中通常称为SAD)在左右立体图像中找到匹配区域。 该算法绝对不是最新技术,而是说明了立体声匹配概念.
该算法假定输入图像已被校正且未失真.
该算法的输入是:
*窗口大小-用于比较的当前像素周围的矩形窗口的大小(宽度和高度)。Window size *最小视差-开始在右侧图像中搜索匹配区域的最小像素偏移。Minimum disparity *最大视差-停止在右图像中搜索匹配区域时的最大像素偏移。 Maximum disparity
可以将偏移可视化为将右立体声图像向右移动指定像素数
以下伪代码描述了算法(单个着色器算法伪代码。 该算法的代码可以在``stereopass.frag''源文件中找到。)
遍历 左侧图像中的每个像素:
遍历 完整范围的视差值:
逐像素求和,左右窗口之间的绝对差
(右窗口移动了当前评估的视差值)
存储总和最小的视差值
将存储的视差值分配给视差图像像素
该算法是使用GLSL着色器实现的。 创建了该算法的两种实现,以使用两种不同的方法比较执行速度。 第一种版本使用单个着色器和单个渲染通道,而第二种方法使用多个着色器和多个渲染通道来创建视差图像。
单着色器算法经常地重新计算左和右图像的像素之间的相同的绝对差异。 例如,当将3x3窗口水平移动一个像素时,将重新计算6个绝对差值。
而在多个着色器算法中,在对窗口进行求和之前,预先计算像素之间的绝对差。
多个着色器算法包括4次传递:
第一个通道:清除通过-创建两个浮点纹理以存储到目前为止计算出的最小总和(SAD)和最佳视差值(在以下讨论中称为视差纹理)。 最小总和存储在图像的第一通道中,而最佳视差存储在第二通道中。
需要两个纹理,因为着色器在计算期间无法读取和写入相同的纹理。 一种纹理用作输入,另一种用作输出。 计算后,将交换输入和输出纹理。
该技术称为对纹理进行ping ponping或翻转。 清除通道初始化两个纹理。 该代码可以在``clear.frag''中找到 第二个通道:减去通过-考虑16个视差值,并从左图像中减去右移图像。 像素值的绝对差存储在四个输出图像之一的四个通道之一中。 在此过程中,使用了现代图形卡的多重渲染目标(MRT)功能。
该代码可以在``subtract.frag''中找到 第三个通道:聚合通道-减法通道期间生成的16张图像用作该通道的输入。 对于每个图像,计算并存储以当前输出像素为中心的窗口上的总和。
然后,将16张图像的最小和与之前遍计算的最小和(从输入视差纹理读取)进行比较。 如果它较低,则使用新的总和和新的视差值更新输出视差纹理,如果不是,则复制旧值。 该代码可以在``aggregate.frag''中找到 第四个通道:选择通过-最终视差纹理包含在第二个(绿色)通道中找到的最佳视差值。 此过程仅将第二个通道复制到输出图像的所有颜色通道。 该代码可以在``select.frag''中找到
多次执行减法运算和合计运算以覆盖整个请求的视差范围。 需要将视差范围除以这些遍的16个组合。 尽管该算法看起来很复杂,但它的执行速度比单遍算法更快