树莓派上的立体视觉和深度知觉

随着树莓派超低成本的计算模块的发布(请看see www.raspberrypi.org/raspberry-pi-compute-module-new-product/),依赖于树莓派简单的编程环境,简单硬件扩展和丰富的开发资源,使我们利用树莓派创造大量的产品变得可能,

Pi具有强大的多媒体处理能力,但是因为通常在Pi上编程比较简单直接,最大限度的利用其多媒体系统和为它的VideoCore模块编程是较复杂的。

Argon Design精通于在此类系统上的编程,并且可以优化树莓派上的多媒体算法。为了评测计算模块的能力,展示我们的技能,我们设计了本次展示。

4784dd56c9ba9956688de933a7da5e28f3aaca

这次展示是关于立体深度感知-利用两个放置位置具有一定间距的摄像机,从不同的视角拍摄物体来获取深度信息。与此同时这还使用了树莓派计算模块的另一个令人兴奋的特性,那就是它支持双摄像头(标准树莓派仅仅支持单一摄像头)

###立体深度感知

—————————–

深度感知方面的文献中记录了很多好的算法。它们中很多使用了相同的视频压缩算法,Argon Design在这个领域有丰富的经验。都是基于把图像分成块,对于每幅图像中的每个块,在另外的一个或多个图片中搜索“匹配”的块。

ff455f208354e1f0bb9409215c070994143130

然而,与视频压缩相比,深度知觉需要更加可靠的结果。文献中还记载了很多改善输出的基本算法。因为这只是一个概念验证,所以我们的标准是选择那些不需要花费太长时间去实现的改进算法,这些算法不需要很大的计算量并且可以给出相当好的改善结果。基于块的视频压缩和我们最终的算法之间最基本的差别在于:

– 对比两个间距已知的摄像机同时拍摄的两幅图片。这表示我们在测量视差,我们可以通过它来得到摄像机和物体的间距。对于视频压缩我们则会去对比同一个摄像机在不同时期拍摄的几幅图片,所以这种算法意在测量运动。

– 假设摄像机都是水平对齐的。这使得二维搜索降低到一维,节省了大量的处理时间。这需要对摄像机进行校准,不过我们可以使用已知的方法来进行校准,人工的或者自动的都可以。

45353b9302a24a1e55a0cd8b44ce50b9195aff

– 使用更加准确(但是更加耗时)的方法来测量两块之间的相关性,基于如下两篇文章:
– [1]. Heiko Hirschmüller, “Improvements in Real-Time Correlation-Based Stereo Vision” CVPR 2001
– [2]. Olivier Faugeras et al, “Real t ime correlation-based stereo: algorithm, implementations and applications” INRIA 1993

特别的,我们决定结合使用[2] 中的”C5″相关方程(“C5″ correlation function)和[1]中提到的多窗口方案(multi-window scheme)。总的来讲,我们的程序既可以使用5×5窗口方案或是7×7方案。7×7的方案计算时间更长但是也会稍微准确一些。

###性能

——————————

使用了三种不同版本的实现方式:

– 原始版本使用Python和NumPy,用以评价其他方案的准确性。

– 使用C语言的版本,在变换中尽可能多的使用算法来增强效果。最大的改进来自于通过仔细的安排代码来避免冗余的计算,我们也使用了一个自定义的排序网络来替代通用排序算法(多窗口方案使用的算法),速度提高了大概4倍。

– 使用VideoCore的视频处理单元(VPU)的汇编程序,使用了C版本的结构但是利用了VPU的架构特性(比如说它的16路向量单元(16-way vector unit )和16KB的处理器局部储存器(processor-local memory)

fda3ed7ee2b4eeb153b49d40e45bdfb5b856c8

一个中等大小(768×576像素)的图像,在不同版本下的处理时间大概是:
– Python, on x86 (~3GHz): 63 seconds
– Python,x86平台(~3GHz):63秒
– C, on x86 (~3GHz): 56 milliseconds
– C,x86平台(~3GHz):56毫秒
– C, on Pi ARM core (700MHz): 1 second
– C, 树莓派ARM内核(700MHz): 1 秒
– Assembler on VideoCore VPU (250MHz): 90 milliseconds
– 汇编,VideoCore视频处理单元 (250MHz):90毫秒

请注意VideoCore版本仅仅比x86平台上的C版本耗时长大约50%,而x86平台比VideoCore的时钟速度快了12倍。

我们还编写了一个演示程序,它会从两个摄像机获取图像,处理他们并且把计算得出的深度数据以彩色的方式显示。摄像机的处理和展示会添加少量的补偿,来对我们减小图像尺寸到VGA (640×480)进行补偿
最终的帧速率是12fps。对于概念验证已经足够,同时在某种程度上展示了图像处理工作,而且我们可以用比较合理的开发速度在树莓派上实现它。

###应用

我们创建的示例程序可以以下面三种不同的方式进行展示

– 仅显示摄像机原始图像
– 把视差数据转换为彩色数据并覆盖在图像上
– 把距摄像机某个距离上的所有点全部移除

结果的截图如下,同时还有一些用到的设备的照片。

784de1bb92719537f2c0b93a1815d78850348e

然而,能做的不仅仅只有这些,还包括:

– 把两个或多个摄像机的图片缝合形成全景图

– Argon之前做过的一个项目是使用扩展卡尔曼滤波(Extended Kalman Filter)来分离摄像机的运动和一个场景中物体的运动。结合这些可以生成某个环境的动态的3D地图。

– 展示程序中的背景一处会切掉物体的一部分,这个问题可以结合边缘检测滤波的结果来进行补救。

– 这一算法非常适合在FPGA上执行,因为大多数的计算都可以并行工作。因此上面介绍的任何东西都可以轻松的提高到实时处理1080p30或4K视频。

###使用到的技能

[软件工程](http://www.argondesign.com/what-we-do/#software_engineering),

[处理器架构](http://www.argondesign.com/what-we-do/#processor_architectures),

[算法及运算](http://www.argondesign.com/what-we-do/#algorithms_mathematics),

[图像处理](http://www.argondesign.com/what-we-do/#image_processing),

[多媒体](http://www.argondesign.com/what-we-do/#multimedia )

树莓派上的立体视觉和深度知觉,首发于极客范 – GeekFan.net