移动设备上USB摄像头的功能实现方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
移动设备上USB摄像头的功能实现方法研究摘要:针对android操作系统下无法使用usb摄像头进行预览和拍摄的问题,提出了在硬件抽象层编写代码进行实现的方法,实现了usb摄像头的正常取景预览和拍摄功能。
在深入研究v4l2规范的基础上,对图像采集驱动uvc进行配置,而后在android系统的硬件抽象层编写了基于v4l2规范的图像采集程序,实现了android操作系统下usb接口摄像头的预览和拍摄功能。
实验测试结果表明,该方法可以获得稳定流畅的拍摄预览效果,并拍摄得到优质清晰的图像。
关键词: usb摄像头;video for linux 2编程;硬件抽象层;色彩空间转换
中途分类号:tu-024 文献标识码:a文章编号:
0 前言
基于android操作系统的嵌入式平台,凭借其开放性、友好的用户界面、优秀的多任务处理能力、强大的多媒体应用,已成为众多嵌入式系统应用平台和移动设备开发平台中的佼佼者。
android操作系统对usb总线接口热插拔的支持非常完善,但对usb摄像头缺乏必要的应用支持。
然而,usb接口具有数据传输速率快、可扩展性好和维护方便等优点[1],usb摄像头可动态连接并延伸一定距离安装,使之非常适合于工业现场监控、图像采集和机器视觉等方面的应用。
为了解决基于android操作系统的嵌入式系统平台中usb摄像
头的应用问题,本文在深入研究了android系统中camera的原理机制和视频设备驱动v4l2标准的基础上,对图像采集驱动uvc进行了配置,编写了基于v4l2的图像采集程序,在硬件抽象层下完成了图像预览及拍摄功能的设计,实现了android操作系统usb接口摄像头取景预览和拍摄功能。
为工业现场监控、图像采集和机器视觉等使用usb摄像头的应用,提供了一种实现取景预览和拍摄功能的方法。
1 开发环境简介
嵌入式系统的开发环境称为交叉式开发环境,所有开发工作在宿主机上完成,产生的代码则运行在目标机上。
宿主机使用pc机,目标机则使用一块arm开发板。
宿主机用于编译生成修改过的摄像头硬件抽象层模块,其使用的操作系统为ubuntu 10.10,编译器使用android源代码中自带的编译器进行编译。
目标机是运行目标代码的机器,它使用移植的android 2.3.4
操作系统,部分代码经过修改,底层为linux2.3.26内核。
2 功能实现原理
本文主要目的是在目标机上的android系统中的硬件抽象层实现usb摄像头的预览及拍照,为上层系统调用提供相应的功能,主要包括两个步骤:
配置系统内核,加载uvc设备,使系统可以识别usb摄像头。
修改系统中摄像头的硬件抽象层,依照v4l2编程规范,在硬件
抽象层实现usb摄像头的预览及拍照功能。
uvc协议的实质是给usb接口的视频设备提供一个统一的数据交换规范。
网络摄像头是第一个支持uvc,也是数量最多的uvc设备。
使用uvc技术的设备还包括摄像头、数码相机、电视棒及静态影像相机等设备。
如果某些视频设备不支持uvc标准协议,则需要独立开发支持该类设备的驱动程序,使内核能够成功识别并驱动该设备。
在v4l2驱动开发框架下,摄像头是一个字符型设备,使用struct video_device结构体表示它。
可以通过标准的系统调用去操作它。
如用open()和close()打开或关闭v4l2设备;用ioctl()对v4l2设备进行控制操作;用mmap()实现映射内核空间地址到用户空间;用read()和write()实现v4l2设备的数据数据读写等。
摄像头设备不仅有读写功能,还有其他的一些功能,可以通过ioctl()命令对设备的操作,给驱动程序发送命令、传递不同的参数,可实现包括查询当前设备的属性、设置视频制式和帧格式等功能。
v4l2视频采集需要按照标准的步骤去完成,其主要步骤如图1所示。
具体使用方法如下:
打开视频设备
usb视频设备是一个字符型设备文件,使用open系统调用。
使用ioctl()系统调用,传入vidioc_querycap参数,通过对结构体
的查询判断,得知该设备是否具有视频采集以及视频流内存映射功能。
传入vidioc_s_fmt参数,通过对结构体的填充来设置视频采集格式及相关信息。
向内核空间申请数据帧缓冲区
使用ioctl()系统调用,传入vidioc_reqbufs参数,通过对结构体的填充,分配视频数据缓冲区。
使用ioctl()系统调用,传入vidioc_querybuf参数,通过对结构体操作,把获取的帧缓冲区的地址转换成物理地址,使用mmap()系统调用将内核中缓冲区映射到应用程序地址空间,这样用户空间就可以直接读取内核空间的视频数据,减小系统的开销;传入vidioc_qbuf参数,通过对结构体操作,数据帧缓存区入列为载入数据做准备。
开始视频采集
使用ioctl()系统调用,传入vidioc_streamon参数开始视频采集函数。
传入vidioc_qbuf参数,将存有图像数据的缓冲区出列读取。
将缓冲区重新入队列尾,循环采集。
传入vidioc_dqbuf参数,将前一步中出队列的缓冲区重新入队列。
传入vidioc_streamoff
命令结束视频采集函数,使用munmap()系统调用逐一释放缓冲区,使用close ()系统调用关闭设备。
3 预览与拍照功能在android系统中的实现
摄像头所有的功能都在hal层进行实现,在hal层中需要遵照v4l2标准调用内核中的摄像头驱动取出图像数据,实现功能供上层软件调用。
在本文中,实现摄像头的预览及拍照功能,应该按照以
下步骤进行:
调用底层驱动获取图像数据;
将图像数据传递给上层应用程序进行显示;
将图像数据信息加上其他信息传递给上层应用保存为图片。
本文中使用的摄像头提供的图像数据格式为yuv420,大小为320*240,而显示系统需要使用rgb565格式的图像进行显示,因此需要将其进行转换。
yuv格式转rgb格式的公式如公式1所示:(1)公式1涉及大量浮点运算,在移动平台上进行计算耗费时间较长,因此在实际应用时可以使用简化为整数运算的近似公式或者使用查表法。
本文中,将rgb565图像数据直接保存为bmp图像,需要为图像信息加上相应的bmp文件头和bmp信息头,其中bmp文件头记录了bmp图像的大小等信息,bmp信息头记录了bmp文件的尺寸及格式信息。
将完整的bmp图像文件传递给上层应用,可以直接保存为bmp 格式图片。
这一步骤通常在摄像头的拍照线程中实现。
4 测试结果
按照上面的步骤对hal层进行修改,并重新编译摄像头模块代码,最终生成libcamera.so动态链接库,将其放入目标机的
/system/lib中,重启加载动态库后,android系统中的camera即可实现usb摄像头的取景预览和拍摄功能。
图2为测试过程中拍摄得到的一副图像,其中左边为取景预览示意图,右边为摄像头拍摄得到的图片。
5 结论
本文在嵌入式android开发平台上成功实现了usb摄像头的驱动、图像数据采集以及拍摄预览和拍摄功能。
在测试过程中,预览图像显示稳定流畅,拍摄得到图片质量得到优质清晰,并可存储至sd卡等设备中。
通过测试分析可以得出以下结论:
通过内核加载uvc的方法可以驱动和识别所有支持uvc的usb 摄像头;
v4l2视频设备驱动提供了数字图像采集所需的功能;
通过改写hal层实现usb摄像头的视频预览和拍摄功能的方法是一种可行而且高效的方法,适合实际的应用环境。
参考文献
[1] 刘飞,张曦煌.基于嵌入式平台的usb摄像头驱动程序的实现[j].计算机工程与设计.2008,29(8):1994-2142
[2] 王飞,孔聪. 基于v4l2的linux摄像头驱动的实现[j]. 电子科技. 2012,25(2):86-92
[3] 张辉,李新华,刘波,钱翔.基于v4l2的视频采集缓存机制应用与实现[j].现代电子技术.2010, 33(20):54-56
[4] 徐家,陈奇. 基于v4l2的视频设备驱动开发[j].计算机工程与设计.2010,31(16):3569-3572。