文章快速检索  
  高级检索
多图像传感器数据采集系统设计与实现
王鑫 , 付永庆
哈尔滨工程大学 信息与通信工程学院, 黑龙江 哈尔滨 150001     
摘要: Android系统作为主流的嵌入式操作系统之一仅能提供对单一图像传感器的支持,因此不能满足人们对多图像传感器的数据采集需求。针对这一问题,文中提出了解决方案。该方案采用FPGA作为传感器采集接口,使用接口共享的方式与传统ARM处理器的图像采集口相连,在用户层采用Android NDK技术控制GPIO使用自定义协议与FPGA交互,最终可以实现对多图像传感器的控制和图像采集。实践证明,该方案可以较好地解决多传感器图像的预览和采集问题,在视频监控、全景成像等领域应用广泛。
关键词: 图像传感器     Android NDK     FPGA     V4L2     JNI    
Design and implementation of multi-sensor image capture system
WANG Xin, FU Yongqing
College of Information and Communication Engineering, Harbin Engineering University, Harbin 150001, China
Abstract: Android system as one of the mainstream embedded operating system can only provide support for single image sensor which cannot meet the demand for multi-sensor image data capture. To solve this problem, this paper presents a program that uses FPGA as image capture interface, and connects ARM processer and field programmable gate array (FPGA) in an interface-sharing way. In application level, Android NDK technology is used to control GPIO that communicates with FPGA under a custom protocol. Ultimately it can achieve control over multi-sensor image sensors. The practice shows that the program can provide a better solution to multi-sensor image preview and data capture, and it can be widely used in video surveillance, panoramic imaging and other fields.
Key words: image sensor     Android NDK     FPGA     V4L2     JNI    

图像传感器作为目前视觉信息获取的一种基础器件,因其能实现信息的获取、转换和视觉功能的扩展,给出直观、多层次、内容丰富的可视图像信息,因而在现实社会生活中得到越来越广泛的应用[1]。然而单个图像传感器不可能获取系统所需的全部信息[2],存在获取图像单一、观察范围过小等缺陷。与采用单一传感器信号相比,来自多个传感器的信号所提供的信息具有冗余性、互补性[3], 在视频监控等领域有着重大意义。目前市面上基于ARM核心的集成芯片仅提供1~2组CSI接口(camera sensor interface),主流的嵌入式操作系统如Android系统也仅提供前置和后置2组图像传感器的支持,并不能满足2个以上图像传感器数据采集的需求。现有方案多采用全景云台的方式进行拍摄,拍摄时间较长、成本较高,并没有实现对CSI接口的共享,无法一次性获取多个传感器的数据内容。文中采用FPGA和android NDK (native development kit)技术实现了1种接口共享的多图像传感器数据采集系统的解决方案,传感器以现场可编程门阵列(field programmable gate array,FPGA)作为中介,通过1组通用CSI口与imx536处理器相连,可以实现8个图像传感器的视频实时预览和图像采集。

1 硬件实现

文中设计中采用的图像传感器为8个OV3640,这是一款300万像素的CMOS图像传感器,分辨率为2 048×1 536。ARM处理器选用的是飞思卡尔的imx536处理器,该处理器基于ARM-Cortex A8内核,提供2组CSI接口,每组接口涉及到的引脚有像素时钟引脚PCLK、行同步引脚HREF、场同步引脚VSYNC和8位的数据引脚DATA。其中HREF信号高电平期间数据有效,其余时间数据无效。每个像素点的数据分2个时钟周期进行传输,传输顺序可以为YUYV。

显然,连接8个图像传感器需要的引脚数量远远超过了ARM处理器能够提供的数量,不可能直接与ARM处理器相连接。考虑到FPGA拥有可编程的引脚众多,适合处理硬件时序等特点,在这里我们选用了FPGA作为imx36处理器和图像传感器中间的中介。此处选择的芯片型号为EP2C5Q208C8,共208个引脚,满足设计要求。首先将所有的8个图像传感器连接到FPGA上,由FPGA进行数据的选通和时序的处理,最终从FPGA引出1组接口与imx536的CSI接口相连,为了进一步压缩所用的引脚数量,考虑到8组传感器的时序具有同步性,我们使用FPGA为所有的传感器提供统一的时钟信号,并在硬件PCB设计上采用等长线设计,这样可以保证所有传感器拥有近似统一的时序特性,因此仅需获取1个传感器的像素时钟信号、行同步信号和场同步信号即可获取整个传感器系统的时序特征,从而达到节省引脚资源的要求。最终的系统框图如图 1所示。

图 1 系统硬件互连框图
2 FPGA与ARM的接口设计

完成了硬件互连设计后,还需要设计FPGA的功能使其允许imx536控制图像传感器,实现传感器切换、视频预览模式和拍照模式切换等功能。

考虑到imx536核心板提供了通用输入输出(GPIO)引脚,我们可以通过GPIO控制FPGA,通过FPGA的内部逻辑实现以上切换功能。

FPGA功能由3个模块组成:时钟模块、数据选通模块和控制模块。其中时钟管理模块产生系统工作时钟和8个同频同相时钟作为摄像头的主时钟;数据选通模块与8个传感器的数据引脚相连,根据控制模块的控制信号选通对应的摄像头数据;而控制模块则负责接收ARM处理器的3个GPIO信号。文中设计中采用了imx536的3个GPIO引脚来实现,分别为模式切换引脚MODE、摄像头选择引脚CHANGE和发送引脚SEND。具体工作流程如下:

视频采集模式时MODE引脚为低电平,每当检测到CHANGE引脚的上升沿,FPGA输出的传感器数据依次从1号传感器至8号传感器切换。视频预览模式下的时序图如图 2所示,图中CAMn代表来自第n个图像传感器的数据。

图 2 预览模式时序图

当MODE引脚置位高电平时系统进入拍照模式,此模式下FPGA会依次发送来自不同摄像头的帧数据,第1帧图像来自1号摄像头,第2帧图像来自2号摄像头…以此类推。在进入拍照模式后,FPGA会检测SEND信号的电平,SEND信号低电平时FPGA会将所有输出置0等待Linux内核分配内存资源,待资源分配完毕后处理器会将SEND信号置高,此时FPGA将检测摄像头的场同步VSYNC信号,VSYNC信号的上升沿会自动触发内部的计数器实现摄像头数据的切换,无需CHANGE信号的参与。数据的切换发生在VSYNC信号的高电平期间,此时数据是无效的,因此切换数据并不会对ARM处理器的接收产生影响。此模式的时序图如图 3所示。

图 3 采集模式时序图
3 软件实现 3.1 程序框架

首先介绍一下图像采集系统中用到的程序框架。由于Android系统采用的是Linux内核。因此我们可以借鉴Linux下的视频处理框架。

V4L2(video for linux 2)作为Linux系统下的一种通用的视频架构,应用于许多嵌入式视频设备ARM之中,已形成了主流的应用模式[4]。V4L2属于2层的架构[5], 顶层为应用程序接口,底层为内核中的驱动程序。文中主要介绍顶层代码的编写。V4L2采用ioctl的方式实现用户空间程序对内核空间设备文件的访问。根据不同的功能,V4L2框架提供了以下的接口供用户层调用,如表 1所示。

表 1 V4L2提供的接口
命令标识符 含义
VIDIOC_REQBUFS 分配内存
VIDIOC_QUERYBUF 把分配的数据缓存转换成物理地址
VIDIOC_S_FMT 设置当前驱动的频捕获格式
VIDIOC_G_FMT 读取当前驱动的频捕获格式
VIDIOC_QBUF 把数据从缓存中读取出来
VIDIOC_DQBUF 把数据放回缓存队列
IDIOC_STREAMON 开始视频显示
VIDIOC_STREAMOFF 结束视频显示

在Linux中图像传感器可以看作是设备文件,可以象普通文件一样进行访问,本设计中图像传感器虽然并没有直接连接到imx536处理器中,而是用FPGA做中介,但是由于FPGA的输出符合CSI接口的时序要求,故从ARM处理器的角度可以把FPGA当作一个虚拟的图像传感器来处理。这个设备被挂载在/dev/video0上。我们可以简单地使用open函数获取它的文件描述符并对其进行操作。

int fd=open (“/dev/video0”, O_RDWR, 0);

利用表 1中的接口我们可以方便地实现对设备的操作,例如开始视频显示的代码如下:

ret=ioctl (fd, VIDIOC_STREAMON, & type);

其中ret为函数的返回值,正确为0,错误为负值,type为v4l2_buf_type类型的指针,代表设备的类型。

V4l2采用缓存队列的方式来提升视频处理的效率保证视频的连续性。处理器将CSI接口传递来的数据进行依次入队的操作,用户使用VIDIOC_REQBUFS[6]向内核申请一定数量的内存作为缓存队列,使用VIDIOC_QBUF将申请到的内存入队。内存的类型设为V4L2_MEMORY_MMAP,这样我们可以通过地址映射的方式在用户空间直接操作内核空间的缓冲内存地址。

在我们的设计中需要注意的是,为了保证由FPGA送来的8个摄像头数据互不重叠,需要准备8个独立的缓存区,考虑到每帧图像的大小有300万像素,而内核空间中可分配的内存资源有限,通过VIDIOC_REQBUFS我们不可能申请到8个如此大的缓存区,实际只能分配到3个左右。解决这一问题有2种实现方法:

方法1  在向内核请求分配内存时不使用V4L2_MEMORY_MMAP,而是直接通过V4L2提供的V4L2_MEMORY_USERPTR属性直接在用户空间分派内存。但这种方法需要驱动程序的支持,实现起来难度较大。

方法2  依旧使用V4L2_MEMORY_MMAP分配内存,获取到内存的首地址后使用memcpy等函数将数据拷贝到用户空间进行操作。该方法适合需要对数据进行长时间处理的情况下使用,避免了长时间直接在内核空间操作可能带来的后续数据覆盖已有数据的情况。本设计中采用了方法2实现。

最终的程序流程如图 4所示。

图 4 采集程序流程
3.2 NDK程序设计

NDK即Android Native Development Kit,是谷歌推出的C/C++开发工具。一般的安卓应用程序采用JAVA作为主要的开发语言,但是JAVA本身运行效率较低且缺乏访问底层硬件的机制。NDK可以将本地C/C++组件代码嵌入到应用程序中使用[7],解决了以上难题。Android NDK还集成了交叉编译工具[8], 使用ndk-build命令可以直接编译生成目标对应的so文件。

在原生Android系统中实现拍照有2种方式:第1种使用Android SDK中自带的Camera类来拍照,使用这种方法比较便捷,但是由于使用Java开发无法完成对底层设备的直接操控,且无法使用Camera类来控制GPIO。第2种方法即上文提到的NDK开发的方式,我们将访问底层硬件驱动和GPIO的代码封装成1个本地类JNICamera,通过JNI接口来实现所需的功能。

Android系统采用了分层的架构[10], V4l2驱动位于Linux内核,为了直接对驱动进行访问,我们首先要封装一个JAVA类作为接口。文中设计的代码如下:

public class JniCamera {

public static native int takePicture ();

public static native int prepareBuffer ();

public static native int camSel ();

public static native int setMode (int mode);

}

在这个类中定义了4个本地方法,分别对应拍照、内存分配、摄像头选择和模式切换4种功能,这些方法的具体实现将在用C语言编写的代码中定义。takePicture方法和prepareBuffer方法的工作流程可参照上文对V4L2设备的操作。当调用setMode方法时根据传入的参数决定MODE引脚的电平;调用camSel方法时,首先将CHANGE引脚置位高电平,使用usleep函数休眠1ms后再将其拉低,最终输出的结果就是CHANGE引脚产生了一个1 ms的高电平脉冲,供FPGA检测并执行相应的操作。

4 硬件实现与实现结果

为了实现尽可能大的图像覆盖面积,8个图像传感器采用了八面柱体的结构,上面板为FPGA的采集板,上面板采集的数据通过排线与下面板的CSI接口相连。系统实物图如图 5所示。

图 5 系统实物图

拍照模式下同时采集到的8张图片如图 6所示,图中每一张图片来自1个摄像头,实现了单次获取多张图片数据的目的。图片素材有一定的重叠范围,为后期的图片拼接等处理算法提供了方便。

图 6 采集到的图片
5 结束语

文中通过FPGA和Android的NDK开发技术,使用接口共享的方式实现了多图像传感器数据传输,解决了传统CSI接口只能支持单一传感器的缺陷。此方案对于多传感器监控和全景成像均具有指导意义。在下一步研究中可继续优化图像传输的效率和内存的使用。

参考文献
[1] 倪景华, 黄其煜. CMOS图像传感器及其发展趋势[J]. 光机电信息 , 2008 (5) : 33-38
[2] 李郁峰.像素级多传感器图像融合方法研究[D].成都:西南交通大学, 2013:1-7.
[3] 刘贵喜.多传感器图像融合方法研究[D].西安:西安电子科技大学, 2001:1-9.
[4] 郝俊, 孟传良. 基于V4L2的ARM11 USB视频采集终端的设计与实现[J]. 贵州大学学报:自然科学版 , 2011, 28 (4) : 74-78
[5] 张辉.基于V4L2的嵌入式视频驱动程序开发与实现[D].合肥:安徽大学, 2010:41-45.
[6] 张辉, 李新华, 刘波, 等. 基于V4L2视频采集缓存机制应用与实现[J]. 现代电子技术 , 2010 (20) : 54-56
[7] 赵宏伟. Android NDK开发环境实现与应用[J]. 电脑知识与技术 , 2010, 35 (6) : 10055-10057, 10060
[8] 王有禄, 李代平. Android系统下基于NDK方式的图形开发[J]. 计算机系统应用 , 2012, 21 (12) : 56-59
[9] 朱国斌.基于Android系统的Camera模块设计和实现[D].西安:西安电子科技大学, 2011:17-20.
[10] 刘红保. Android系统下Camera子系统的设计、实现与优化[D].北京:北京邮电大学, 2012:27-40.

文章信息

王鑫, 付永庆
WANG Xin, FU Yongqing
多图像传感器数据采集系统设计与实现
Design and implementation of multi-sensor image capture system
应用科技, 2016, 43(6): 38-42
Applied Science and Technology, 2016, 43(6): 38-42
DOI: 10.11991/yykj.201511004

文章历史

收稿日期: 2015-11-04
网络出版日期: 2016-11-27

相关文章

工作空间