实现OpenCV的视频图像处理
0赞嵌入式ARM及ARM-Linux操作系统已广泛应用于工业控制、通信、医疗仪器等各个领域。ARM设计了大量高性能、廉价、耗能低的RISC处理器、相关技术及软件。技术具有性能高、成本低和能耗省的特点。适用于多种领域,比如嵌入控制、消费/教育类多媒体、DSP和移动式应用等。 许多公共场所和居民小区等地点都安装了视频监控系统,因而视频监控与显示终端的应用越来越广泛。
本文以嵌入式ARM作为硬件核心,ARM异步响应方式异步响应方式ARM也是一种非平衡数据链路操作方式,与NRM不同的是,ARM下的传输过程由从站启动。从站主动发送给主站的一个或一组帧中可包含有信息,也可以是仅以控制为目的而发的帧。在这种操作方式下,由从站来控制超时和重发。该方式对采用轮询方式的多站链路来说是必不可少的。采用上述平台具有以下优点:(1)ARM-Linux与OpenCV库同为开源的免费软件,开发者不仅可以根据需要修改源代码来提高软件开发的灵活性,而且可以节约开发成本;(2) OpenCV库提供了许多视频图像处理的函数,因此开发者不需要花费大量的时间自己编写,可以提高软件的开发效率;(3)OpenCV库中大部分函数都经过汇编优化,基于OpenCV的程序运行起来有更高的效率。
视频监控与显示系统的硬件和软件结构如图1所示。
硬件由三部分组成:(1)摄像头。负责采集原始视频流数据;(2)ARM开发板。负责处理原始的视频流数据;(3)LCD液晶显示器。负责图像数据的显示。软件部分也由三部分组成,这三部分运行在ARM-Liunx操作系统下:(1)摄像头驱动程序;(2)摄像头应用程序;(3)LCD显示驱动程序。
1 嵌入式系统应用程序开发方法
1.1 硬件平台
嵌入式系统开发平台由主机PC机和目标机ARM板组成。
Pentium 4的设计目标是适应更快的时钟速度,因为消费者开始依据更高的时钟购买计算机,是Intel生产的第7代x86微处理器,并且是继1995年出品的Pentium Pro之后的第一款重新设计过的处理器,首款产品代码为:WillAMEtte,拥有1.4GHz左右的内核时钟,并使用Socket 423脚位架构,不同于Pentium II、Pentium III和各种Celeron处理器,因为是全新设计的产品,所以与Pentium Pro的关联很小。值得注意的是,Pentium 4有着非常快速到400MHz的前端总线,之后更有提升到533MHz、800MHz。它其实是一个为100MHz的四条并列总线 ,因此理论上它可以传送比一般总线多四倍的容量,所以号称有400MHz的速度。
所以主机PC要求CPU为Pentium 4或以上,拥有一个25针的并口、一个9针的RS-232串口和一个20GB的硬盘。ARM板是由深圳市武耀博德信息技术有限公司生产的270-S平台。
1.2 软件开发平台
软件程序的开发是在PC机上完成的,PC机上的开发环境是Redhat Linux 9.0。Redhat提供了许多与程序开发有关的工具,还要在PC机的Linux操作系统下安装QT和OpenCV软件工具包。
(1)QT软件包。包括QT/X11 2.3.2库、QT/Embedded 2.3.2库、Qtopia 1.7.0库、uic工具、qmake工具、tmake工具和QT designer工具等。
(2)OpenCV软件包。包括Libhighgui.so.0.9.7、Libhighgui.la、Libcxcore.so.0.9.7和Libcxcore.la等主要的库。
在开发摄像头应用程序之前,要把u-boot、ARM-Linux操作系统和外部设备的驱动程序移植进入ARM目标板270-S中,这样主机PC上开发的各类应用程序软件才能在ARM目标板上运行。
2 摄像头应用程序的构架与关键技术
2.1 摄像头应用程序的结构
应用程序由两部分构成:
(1)在ARM-Linux QT/Qtopia图形操作系统下的窗口界面设计(即人机界面的设计)。
(2)对视频流数据进行处理,并把处理完成的图像数据显示在QT/Qtopia图形界面下。
摄像头应用程序结构图与库函数的调用关系如图2所示。
2.2 摄像头应用程序的关键技术
本设计应用程序以OpenCV库和QT库为核心,负责处理视频数据与图像显示。
2.2.1 OpenCV简介
OpenCV于1999年由Intel建立,现在由Willow Garage提供支持。OpenCV是一个基于BSD许可证授权(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
2.2.2 嵌入式QT与Qtopia简介
QT是跨平台C++图形用户界面工具。由于QT采用面向对象开发,具有跨多平台、界面设计美观等特点,得到广泛应用。因为KDE等项目使用QT作为支持库,所以有许多基于X-Windows的PC机上的应用程序可以非常方便地移植到QT上。
Qtopia 是Trolltech 公司为采用嵌入式Linux 操作系统的消费电子设备而开发的综合应用平台, Qtopia包含完整的应用层、灵活的用户界面、窗口操作系统、应用程序启动程序以及开发框架。 拥有窗口操作系统,游戏和多媒体,工作辅助应用程序,同步框架,PIM应用程序,Internet应用程序,开发环境,输入法 Java集成,本地化支持,个性化选项,无线支持等特点。
3 QT窗体的设计方法
在QT编程中,有两种设计程序窗体(即人机界面)的方法。第一种方法完全采用面向对象的C++编程语言实现,开发者需要手工编写所有的代码;另一种是采用编写代码与QT Designer设计工具相结合的方法。QT Designer工具会帮助开发者完成大部分绘制窗体的工作。本文摄像头应用程序的设计采用第二种方法。QT Designer是QT系统专用的窗口界面开发工具,它不包含任何编译器,而仅仅提供一个可视化界面编辑器。QT Designer将编辑完成的窗体界面通过XML保存为。ui文件,然后由专用的uic界面编译器将其转换为标准C++的源文件。
4 视频图像处理与显示
视频图像处理与显示的过程如图3所示。
其过程主要由四步组成
(1)初始化视频结构
CvCapture*capture=0;
capture=cvCaptureFromCAM(-1);
cvSetCaptureProperty
(capture,CV_CAP_PROP_frame_WIDTH,320);
cvSetCaptureProperty
(capture,CV_CAP_PROP_FRAME_HEIGHT,240);
在OpenCV应用程序中都要定义一个CvCapture类型的指针变量capture。CvCapture类是视频获取结构,它没有公共接口,各类图像数据存储位置的头地址都可以赋值给指针变量capture。在capture指针被赋值之后,可以作为其他图像处理函数的参数使用,完成各种图像处理功能。
OpenCV库中用CvCapture*cvCaptureFromCAM(int index)函数对摄像头分配视频图像数据流和初始化CvCapture结构。函数参数index为摄像头索引值。如果系统只有一个摄像头或者使用哪个摄像头都无所谓,则index的值为-1。
对视频数据结构capture设置参数。用到的OpenCV的库函数为int cvSetCaptureProperty。参数capture指定哪个视频获取结构需要设置参数;property_id为属性标识符,由几个固定值组成,用来决定设置哪个参数。
(2)开启定时器后抓取图像帧
关键代码:
QTimer CameraTimer->start(50,false);
int cvGrabFrame(capture);
IplImage*frame=cvRetrieveFrame(capture);
如果视频结构初始化成功,则开启由QT库提供的QTimer定时器。代码表示为:CameraTimer->start(50,false)。参数“50”表示QT定时器每隔50 ms触发一次。
该槽函数抓取一帧图像的方法为:首先调用OpenCV库函数int cvGrabFrame(CvCapture*capture);从摄像头实时采集的视频流中快速抓取一帧图像数据,并且把这帧图像数据存入ARM板的缓存中,这帧图像数据对于用户是不可见的。采用这种机制,是因为cvGrabFrame()可以把一帧图像数据以最快的速度存入缓存中[1]。
接下来,调用OpenCV库函数cvRetrieveFrame()。这个函数把刚刚通过cvGrabFrame()抓取的一帧图像数据从内部缓存重新读取出来。具体代码为:IplImage*frame=cvRetrieveFrame(capture)。事实上在调用这个函数后,OpenCV内部会完成多步复杂的图像处理的工作。
(3)视频格式的转化
关键代码:
for(int y=0;y<height;y++)
{ for(int x=0; x<width; x++)
{ for(int i=0;i<3;i++)
{*dst++=*frame->imageData++;}
*dst++=0;}}
由于cvRetrieveFrame()重新读取到的一帧图像数据是IplImage类型,IplImage类型是24位真彩的三通道BGR(BGR24),而QT库内与图像处理与显示相关的函数只支持对1 bit、8 bit或者32 bit的位图进行处理。因此为了使IplImage类型帧图像能够在QT/Qtopia图像界面中显示,又不降低视频图像质量,需要通过程序将24位(BRG24)帧图像转化为32位(BRG32)帧图像。
BGR32每一个像素点除了拥有与BGR24相同的红绿蓝三种颜色,每种颜色8 bit外,要还在这三种颜色共24 bit的数据后面添加一组长度为8 bit的0数据。因此,图像格式转化的方法应该在原始的24位图像数据中每隔三个字节加入一个字节的0。下列代码为BGR24->BGR32图像中一个点的转化程序,其中frame->imageData为原始图像的指针,dst为转化后图像的指针。
for(int i=0;i<3;i++)
{*dst++=*frame->imageData++;}
*dst++=0;
(4)将视频图像数据显示在QT/Qtopia图形界面
关键代码:
QImage image=QImage((uchar*)image32,frame->width,
frame->height,32,NULL,0,QImage::LittleEndian);
QPainter display(picCamera);
display.drawImage(0,0,image);
首先调用QImage构造函数把上一步转换好的32位(BGR32)图像数据初始化为QT图像数据格式;然后调用QT的低水平绘制类QPainter的构造函数对主窗口的显示器组建初始化;初始化结束后将调用QPainter类的drawImage成员函数,把通过QImage类转换过的图像数据image绘制在主窗体的显示器中,代码为QPainter.drawImage(0,0,image)。
ARM平台的手持移动监控与显示终端设备已经广泛应用于社会的各个领域。OpenCV图像处理库以其开源性、高效性、灵活性帮助开发者大幅度地缩减开发周期。ARM-Linux QT/Qtopia与其他ARM端的图像界面操作系统相比较有免费、移植性好、内核精简、更加稳定的特点。本设计以OpenCV图像处理库为核心,在ARM Linux QT/Qtopia图形界面操作系统下实现摄像头显示的应用程序,有非常好的实用性,可以广泛应用于各类ARM终端设备中。