文献标识码:A
文章编号: 0258-7998(2015)04-0025-04
0 引言
目前机载字符显示主要分为点阵字符显示与矢量字符显示。两种显示方式各有优缺点,点阵字符大小固定,输出简单;矢量字符大小可调,输出灵活,但依赖于反走样直线与反走样圆弧的实现效果,实现较为复杂。另外,通常字符的旋转、缩放等变换是对字符像素点进行复数乘法运算,计算坐标时存在小数的四舍五入,因此会出现明显的走样现象。
本文综合考虑点阵字符与矢量字符的优缺点,首先在VxWorks[1]操作系统下利用FreeType字体引擎实时提取矢量字形并利用其自带的API函数完成旋转、描边等字形变换,接着再渲染成高质量、抗锯齿的256级灰度值位图,然后通过PCI-E总线将灰度值点阵传输至底层FPGA,最后由FPGA根据优化后的融合算法完成字符与外部视频的叠加并显示。
上述字符生成流程既能灵活实时提取各种尺寸的字符,又可以简单地输出,不失真地旋转,同时还具有优良的描边效果。通过反复验证提出一种背景融合算法,成功解决了字符与视频背景叠加时出现的边缘灰度值突变问题,实现了字符与视频背景的高质量叠加。
1 机载平显系统组成
本文所研究的内容为“新一代机载综合平视显示系统”的重要组成部分,旨在研制拥有自主知识产权、灵活可重构的机载视频处理与图形字符生成系统,形成包括底层硬件平台、系统软件平台、图形字符绘制接口以及底层图形绘制IP核的核心解决方案。
图1为机载平视显示系统的组成框图,它由三大部分组成,其中核心部分机载字符显示系统由4个模块组成,图中各组成部分与模块的功能如下:
(1)字符绘制接口:运行在VxWorks操作系统上[2],根据上层应用程序中有关绘制字符指令中的参数,实时提取出相应字符信息,以特定的指令格式交由PCI-E设备,实现顶层应用程序与底层硬件的无障碍通信。
(2)FIFO(First In First Out,先入先出队列):用于暂存PCI-E设备发送的绘制指令,供底层IP核读取。
(3)绘制IP核取指令:作为底层硬件平台的核心,IP核从FIFO中读取字符绘制的指令,包括字符绘制参数及字符灰度值信息。
(4)视频背景融合:IP核同时读取视频背景的RGB值与加黑边字符的灰度值,按特定算法进行融合处理。
2 字符生成及字形变换
2.1 TrueType字库及FreeType字体引擎
TrueType[3]是苹果公司和微软公司合作开发的一种新型数字化矢量字体格式,采用几何学中的二次B样条曲线及直线来描述字体外形轮廓。本系统暂定需要95个字符,包括26个英文字符的大小写、10个阿拉伯数字和33个标点符号。所以选用Arial.ttf存储在非易失存储器中,上电再调入内存,供字体引擎提取。
FreeType是使用ANSI C开发的开源字体引擎,利用它可以不用关心TrueType字库文件格式,仅需调用FreeType的应用程序接口(Application Programming Interface,API)函数完成大部分的工作,而且FreeType可以在包括VxWorks的多种操作系统平台下编译运行。
针对嵌入式系统存储容量相对较小以及机载平台对代码运行速度的要求,需要对FreeType这个高度可定制的字体引擎进行定制和裁剪[4]。通过对字体引擎的定制和裁剪,有效减小了库文件的体积,加快了代码的运行速度。
2.2 嵌入式矢量字符显示
图2为嵌入式矢量字符显示流程,图中各个模块的功能具体如下:
(1)初始化库并装载字体文件
调用FT_Init_FreeType初始化库,先创建一个FreeType库的新实例,并且设置句柄library为它,然后装载库中的每一个模块。调用FT_New_Face装载字体文件,创建一个新的face对象用来描述一个特定的字样和风格,本系统装载的是Arial.ttf。
(2)设置当前像素尺寸
调用FT_Set_Pixel_Size设置像素尺寸,设置的大小以像素为单位。按照本项目的相关技术协议,字符的尺寸为16×16~32×32范围内的任意值。
(3)装载字形图像
调用FT_Cet_Char_Index得到字符索引,进行相应的字形变换后,再调用FT_Load_Glyph将字符轮廓信息读取到字形槽中。
(4)设置渲染模式获取字符位图
调用FT_Render_Glyph将字符槽中的字形图像转换成一个256级灰度的抗锯齿位图。
2.3 字形变换
调用FT_Set_Transform对其进行仿射变换,完成字形的旋转、倾斜、缩放等操作。本系统要求完成字符的0°~360°顺时针旋转,且是否旋转由上层控制。根据上层给出旋转的角度,对2×2的仿射矩阵赋值。
上一代平显系统中的旋转由底层FPGA实现,但FPGA在计算字符像素点坐标时存在四舍五入,且旋转可能导致的维数变化会造成像素空洞,直接影响显示的效果。利用FreeType字体引擎完成旋转属于对字形图像的变换,基于字符的描述信息而不是字模数据,通过这种方式进行旋转后再提取位图并显示,效果得到明显的改善。图3为两种不同旋转方法得到的效果图。
3 强背景识别技术
在显示机载画面时,由于字符叠加在视频背景上,当字符与背景的颜色相近或视频背景亮度较大时,往往会出现字符看不清楚的情况,给飞行员的驾驶带来潜在的隐患。所以为了在强背景环境下有效识别出字符信息,需要对字符进行描边处理。
3.1 传统字符描边方法
3.1.1 一位二进制字符加一位二进制描边
在上一代平显系统中,字符部分与描边部分每个像素点都使用一位二进制数来表示。当代表像素点的数为1时,表示字符经过此位置,则将该位置的像素设置为字符颜色;当代表像素点的数为0时,表示字符不经过此位置,则将此位置的像素设置为背景颜色。因为每个像素点仅用一个二进制位表示,所以显示在屏幕上时字符锯齿化明显,边缘不够圆润,且旋转后整体较为模糊。
上述二值点阵字符描边方法较为简单,直接在点阵字符的边缘加上黑色边框即可,但是显示效果极为粗糙,如图4(a)所示。
3.1.2 灰度值(256级)字符加一位二进制描边
256级灰度值字符由FreeType提取,并采用传统描边的方法:通过扫描字符点阵的每一个像素点,对每个灰度值不为零的像素点进行判断,若判断为边界点则将该像素点周围四个邻域或八个邻域内灰度值非零的像素点置为描边点。
虽然这种描边方法简单易行,但是实际显示效果并不理想。在初始大小下,可以看到原始字符部分由于使用FreeType提取,效果较一位二进制字符有明显改善,描边部分虽清晰可见,但较为生硬。放大若干倍后,可以发现描边毛刺棱角较多,走样明显,不适于飞行员长期观察,如图4(b)所示。
3.2 FreeType描边
鉴于使用邻域扫描描边方法的显示效果不佳,所以需要寻找另一种显示效果好的描边方法。研究发现调用FreeType自带的API函数对字符进行描边处理效果较好,如图4(c)所示,具体步骤如下:
(1)在进行完字形变化并将字形读取到字符槽后,调用FT_Get_Glyph把字形槽中的字形图像复制到新的glyph1对象中,然后调用FT_Stroker_New创建一个笔触,并调用FT_Stroker_Set设置笔触为描边;
(2)对glyph1的字形调用FT_Glyph_StrokeBorder设置为描边渲染,设置渲染参数,调用FT_Outline_Render渲染这个描边的字形图像glyph1,如图5(a);
(3)调用FT_Glyph_Get_Cbox检索glyph字形图像,获取该描边字形的宽度、高度等信息;
(4)再次调用FT_Get_Glyph把字形槽中的字形图像复制到新的glyph2对象中,重新设置渲染参数,调用FT_
Outline_Render渲染这个字符本身的glyph2,如图5(b);
(5)开辟一个缓存,存放glyph1与glyph2叠加后的像素信息。
4 背景融合技术
与传统加一位二进制描边不同,使用FreeType为字符加上的描边同样具有256级灰度,所以描边显得光滑圆润,但同时也带来了新的问题。由于FreeType中生成的描边信息的边缘基于纯白背景,灰度值会有向255渐变的趋势,所以在黑色背景下边缘灰度值与背景灰度值相差过大,严重影响显示效果,因此需要对描边与周围视频背景作相应的融合处理。
图6为未进行背景融合的数字3在不同灰度值背景下显示的效果。
除在纯白背景下,黑边外都会有与背景不协调的白边,特别在纯黑背景下描边效果最差。图6(a)、(b)、(c)、(d)中背景灰度值分别为:0、127、255、随机灰度值。
将描边的灰度值与背景以一定比例进行融合,使得黑色描边与背景线性相关,可以有效减少描边外围白色边框的产生。目前项目仅要求显示黑白灰度值字符,所以字符RGB 3个分量都等于其灰度值。但是考虑到背景的RGB分量并不一定相等,所以在融合时需要将底层IP核分开计算。
(1)如果为描边:
R[x+r][y+c]=(255-gray[r][c])*bg_R[x+r][y+c]/255;
G[x+r][y+c]=(255-gray[r][c])*bg_G[x+r][y+c]/255;
B[x+r][y+c]=(255-gray[r][c])*bg_B[x+r][y+c]/255;
(2)如果不是描边:
R[x+r][y+c]=gray[r][c];
G[x+r][y+c]=gray[r][c];
B[x+r][y+c]= gray[r][c];
其中x、y为字符在屏幕上的绘制坐标,r、c为当前灰度值点在提取字符中的行号与列号,gray[][]为当前像素点的灰度值,bg_R[][]、bg_G[][]、bg_B[][]依次为背景的RGB 3个分量值。
图7为进行了背景融合后的字符显示效果,其中(a)~(d)背景灰度值为127,(e)为随机彩色背景。
5 绘制指令传输
5.1 上位机绘制接口
为方便上层用户调用绘制字符指令,系统自定义字符绘制接口函数如下:
void WriteChar(int CharSize, int CharCode, int Angle, int X, int Y);
其中X、Y为字符轮廓左上角的横纵坐标;Angle为字符旋转弧度值,范围是0~2π;CharCode为字符ASCII码,范围是33~127;CharSize为字符大小。
5.2 写入FIFO的指令格式
绘制字符指令格式如表1所示。
(1)命令字:五位二进制数,用以确定绘制指令的类型。
(2)字符X坐标、Y坐标:同5.1中X、Y坐标。
(3)总行数、总列数: 发送字符数组的行列数。由底层FPGA根据总行数、总列数计算出总点数,用来判断传输某个字符的最后一个32位数是否写满(当总点数不是3的整数倍时)。
(4)灰度值1、2、3: 3个连续点的灰度值信息,灰度值为0~255,需要8位二进制数表示。
(5)描边点标志1、2、3: 用来判断相应点是否为描边点,如果为描边点则进行背景融合。
5.3 实时性分析
在给定的标准测试画面中,除字符外还有点、线、圆等基本图元。经统计,标准测试画面中3种大小字符平均所需命令数分别为88、196、347。3种大小字符的个数分别为7、89、32。
一帧需要传输的32位长整形数(包括字符和图形指令)约为29 669个,其中字符29 164个,约占98%。
以每秒24帧计,计算后得到的指令吞吐量约为6.79 MB/s。若考虑字符旋转后像素点增加20%,则吞吐量最大约为8.12 MB/s,远小于PCI-E总线的单向数据传输速率2.5 Gb/s,所以字符的传输满足系统的实时性要求。
6 结论
上述在VxWorks中字符的显示方案已经成功应用于机载座舱信息显示系统中,不仅满足机载设备的实时性要求,而且字符生成灵活、显示效果优良,具有相当广阔的应用前景。
参考文献
[1] VxWorks programmer′s guide 5.5 edition 1[Z].Wind River Systems Inc.,2000.
[2] 孔祥营,柏桂枝.嵌入式实时操作系统VxWorks及其开发环境[M].北京:中国电力出版社,2002.
[3] 孙枫,陈业夫,郭勇鹏.在VxWorks系统中使用TrueType字库[J].应用科技,2003,30(11):53-55.
[4] 陈文文,奚宏生.嵌入式系统中的TrueType字体驱动[J].计算机工程,2010,36(7):257-259.