1.4 从桌面移植到嵌入式设备
桌面程序运行成功后,我们就可以从中构建一个嵌入式系统程序。虽然本节给出的详细说明是专门针对树莓派的,但是类似的步骤也适合其他嵌入式Linux系统的开发,比如BeagleBone、ODROID、Olimex、Jetson等。
在嵌入式系统上运行代码有几种不同的选择,每种选择对应不同的场景,都有各自的优缺点。
有两种常用方法用于编译嵌入式设备的代码:
●将源代码从桌面复制到设备上,并直接在设备上进行编译。这通常被称为本机编译,因为我们在最终运行代码的系统上本地编译代码。
●在桌面上编译所有代码,但需要使用特殊方法为设备生成专用代码,然后将最终的可执行程序复制到设备上,这通常被称为交叉编译,它需要特殊的编译器,这种编译器知道如何为其他类型的CPU生成代码。
交叉编译通常比本机编译更难配置,特别是在使用了许多共享库的情况下。但由于桌面通常比嵌入式设备快得多,因此在编译大型项目时交叉编译通常要快得多。如果你需要工作几个月,编译项目数百次,这个时候与台式机相比,你的设备就相当慢了。例如,树莓派1或者树莓派Zero,它们与台式机相比非常慢,这时就可采用交叉编译。但在大多数情况下,特别是对于小型简单的项目,你应该坚持使用本地编译,因为它更容易。
请注意,项目使用的所有库也需要为设备编译,所以你需要为设备编译OpenCV。在树莓派1上本地编译OpenCV需花费几个小时,而在桌面上交叉编译OpenCV可能仅需15分钟。但是通常只需要编译一次OpenCV,然后就可以对所有项目使用它,所以在大多数情况下,仍然值得坚持使用项目的本地编译(包括OpenCV的本地编译)。
如何在嵌入式系统上运行代码有以下几个选择:
●使用与桌面相同的输入和输出方法,例如相同的视频文件、USB网络摄像头或键盘作为输入,并在HDMI监视器上显示文本或图形,一切与桌面相同。
●使用特殊设备进行输入和输出。例如,使用特殊的树莓派相机模块进行视频输入,使用自定义GPIO按钮或传感器输入,使用一个7英寸(1英寸=0.0254米)MIPI DSI屏幕或GPIO LED灯作为输出,而非使用USB网络摄像头和键盘作为输入并在桌面显示器上显示输出。然后再使用普通的便携式USB充电器为它们供电,你可以将整个电脑平台放到你的背包里,或者绑到你的自行车上!
●另一种选择是将数据从嵌入式设备流入或流出到其他计算机,或者甚至使用一个设备输出相机数据,另一个设备来使用该数据。例如,你可以使用GStreamer框架配置树莓派,或者通过以太网或Wi-Fi,将H.264压缩视频从其相机模块传输到网络上,以便强大的PC或者本地网络服务器机架或者Amazon AWS云计算服务可以在其他地方处理视频流。这种方法允许在需要大量处理资源的复杂项目中使用小而便宜的相机设备。
如果你希望在设备上执行计算机视觉程序,注意一些低成本嵌入式设备的限制,如树莓派1、树莓派Zero和BeagleBone Black,这些设备的计算能力远远低于台式机,甚至不如便宜的笔记本电脑或者智能手机,所用时间可能是桌面的10~50倍。因此如前所述,根据应用程序的需求,你可能需要功能强大的嵌入式设备或将视频流式传输到单独的计算机。如果你不需要太多的计算能力(例如,只需要每两秒处理一帧,或者仅需要使用160×120的图片分辨率),那么在树莓派Zero上运行就足以满足需求。但是许多计算机视觉系统需要更强的计算能力,因此如果你想在设备上执行计算机视觉系统,要使用速度更快的设备,其CPU在2GHz范围内,如树莓派3、ODROID-XU4或者Jetson TK1。