1. 引言
颜色作为可见对象的一个主要特征,在物品识别和物体追踪方面应用非常广泛 [1] [2] [3] [4] 。包含颜色识别的投入实际应用的技术也有很多,比如:车辆号牌识别、条码识别、面部信息采集等 [5] [6] 。其中大多数计数研究采用给定样本的方法,也有一部分研究仍停留在Matlab的平台仿真验证的阶段。
本设计以工学角度出发,尝试在不优先考虑性能的情况下设计了一个以使用为基本目的的颜色提取器。根据一般设计规律,本文将设计中面对的所有问题简化为了四个问题:软件结构、算法实现、结果检验、抗干扰,并重点说明其中的颜色提取过程和灰度参考值生成的实现和优化。
本设计的设计目的在于:通过在开环的颜色识别系统中加入具有自评估能力的颜色样本提取器模块,使“当系统得到不符合要求的颜色样本时能够利用提取器产生颜色提取任务的回滚”这样一个可以基于PID技术的最优样本生成的行为成为可能,提高实时识别系统的弹性。
2. 原型设计
接下来将说明原型的设计方案(Alpha版)。由于原型的目的在于功能实现,并没有仔细考虑架构.动态性能.复验结果等问题,所以其中存在一些不太合理的结构。大部分问题将在之后的第一改进方案(Beta版)中给出解决方案。
2.1. 基本设计要求
1) 我们针对的是kinect2的体感摄像头传回的数据,当然这并不意味着我们就不需要读取图像文件来作为提取图像。所以,根据ROS关于话题的特性,我们需要一个接口类去订阅kinect2_bridge发布的图像数据,由于我们并不需要处理过时的图像,所以这个缓存池只需要一幅最新的图像即可,然后通过提取器的查询式接口传回数据。
2) 我们处理对象是八位BGR三通道像素。这是Opencv3中能够使用的最小的彩色像素的格式。即使如此,每个像素仍具有224种组合结果。所以我们需要采用可调节的减色算法减少提取结果的复杂度并将减色比例标注在结果文件中。
3) 为了提高提取速度和提取到的特征的纯净度,我们需要可自主选取地在图像的某个区域内进行提取。同时,为了防止提取区域过大导致被提取像素呈平方化增长,我们需要规定最大提取总数,并且根据提取总数与提取区域的比例自动调节x轴y轴的提取步距。
4) 为了积累实验数据,我们需要将每次的识别结果保存下来,为之后的统计识别结果。所以,我们需要一个基于XML文件技术的可指定路径且以固定格式保存特征文件的读写接口。
2.2. 原型的功能结构示意图
通过如《2.1基本设计要求》的描述,我们基本可以得出如下图(图1模块功能结构示意图)。图中主要说明了《2.1基本设计要求》中的1),4)两点以及其二者必要的环境,关于2),3)两点将在《2.6特征信息提取流程》说明。

Figure 1. Diagram of functional structure of modules
图1. 模块功能结构示意图
2.3. 原型的数据结构
2.3.1. 实现
类数据成员的大致结构如下:
1) 必要的数据存储空间和挂载的类结构。如:图像接口与特征文件保存接口的类指针、图像指针、字符串处理类等。由于图像接口和特征文件保存接口所使用的接口类都是双向的接口类而且原有系统中的调度节点的提取和识别功能并不会同时进行,所以用指针共用一个实例可以节省内存,减少接口数量。
2) 结果登记单元与结果参数列表。结果登记单元包括一个像素的特征,提取范围内的数量,参考灰度值;结果参数列表包括一个结果登记单元的std::vector数组和一组灰度参考值,以及一个减色比例。
3) 参数列表单元与参数列表队列。参数列表单元包括提取范围,提取比例,灰度补偿,特征的操作参数,以及备用参数列表的索引;参数列表队列包括一个外部设置的std::vector数组,一个预设的std::vector数组,还有一个指针索引用来记录当前使用的参数列表。
4) 其他运行参数。
我们需要注意的是:参数列表本身是一组必要参数的集合,这样就导致如果要修改其中一个参数就需要重新输入一组参数。第一,这导致了修改参数的繁琐与过大的开销;第二,由于这样参数结构对只修改其中一部分参数。
我们主要讨论的问题其一将集中在:参数列表单元过大对局部修改兼容性不足导致参数接口过于复杂以及参数列表队列导致的过量冗余。
2.3.2. 优缺点
这样的数据结构的唯一优点是:这个数据结构支持了整个提取过程把功能实现了。
而它的缺点也极为明显:由于我们在《2.1基本设计要求》提出了提取总量不变,提取密度随提取范围变化而变化的要求。由于我们采用了最方便的矩形区域作为提取范围的基本形状,因此为了提取某个非矩形的目标区域,使用者可能会选择多次局部提取来防止提取到不符合要求的区域,如下图(图2多次提取的示意图)所示。深色部分为需要提取的区域。

Figure 2. Schematic diagram of multiple extractions
图2. 多次提取的示意图
这就要求设计里参数列表中各组数据的接口非常灵活且独立。但我们在设计原型的数据结构时将参数列表整体视为了一个单元,如果我们需要有一个参数列表中的某部分的时候,模块会把整个参数列表加载进来。为了在这基础之上制作足够灵活的接口,我们不得不在既有但不兼容的结构之上重新构造另一组更灵活但是功能完全相同的结构来将原来的参数列表的局部屏蔽掉,使用通过接口获得的数据。也就导致了如下图(图3原型设计的参数索引结构示意图)所示的参数索引结构,提取过程的每个子过程由一个函数表示,每个函数具有如图3所示的结构,通过在进入工序后,先加载参数,然后再执行算法函数。在提取过程中,存在两个子过程需要具有这样的结构:1) 提取特征函数,这个函数在取回图像数据后执行,通过读取参数列表中的提取范围和提取密度进行均匀地(等步距)抽样提取。2) 按照提取比例筛选特征函数,这个函数是对提取到的特征的累计结果降序排序,根据参数列表中设定好的提取比例提取满足条件的一组特征。在如图2多次提取的示意图中所示的多次提取过程中,每次提取的范围大小、位置是存在不同的;而如果得到的特征过多或过少,使用者则需要调整提取过程的提取比例,因此从使用角度来讲这样的结构满足了使用要求,但这样随意堆砌的结构让整个模块付出了加载参数部分的结构过于复杂的代价。
2.4. 特征信息提取流程
特征提取流程如下图所示(图4特征信息提取流程图所示)。当颜色特征识别系统的调度环节调用了本设计的特征提取模块的处理函数后,特征提取模块开始进行一次提取。提取模块先通过调用图像收发接口类,取回kinect2传回的图像数据,然后开始检测运行参数是否需要刷新,如果需要刷新,则对需要刷新的部分重新计算,至此提取过程的需要的数据样本和参数设定准备完毕。接下来根据运行参数中的提取范围和提取密度两组参数对取回的图像进行指定范围内的均匀的抽样提取,提取到的特征为包含数量的RGB颜色特征,在“统计相同特征的数量”以前,所有特征的数量均为1。此时,模块提取到的样本中存在大量的重复样本,因此需要通过接下来的“将提取结果按色号排序”和“统计相同特征的数量”以产生颜色特征唯一的统计结果。之后再按统计数量降序排序,按提取比例取出符合要求的特征数据,最终生成一个新的特征文件并把提取结果保存至其中。

Figure 3. Parametric index schematic of prototype design
图3. 原型设计的参数索引结构示意图

Figure 4. Functional structure diagram of module
图4. 模块功能结构示意图
由于原型设计并不考虑计算性能,所以这里使用的排序方法均是最常用的“冒泡排序法”。如果考虑计算性能的话,采用可以适用于多线程开发的排序方法更为合适,比如“奇偶排序法”。
在图4模块功能结构示意图中的“设置灰度参考值”这一工序放在“统计相同特征的数量”之后的原因在于:不论是采用for循环还是采用std::vector迭代器的方法去设置灰度参考值,其处理的数据量越少性能越好。在“统计相同特征的数量”之后得到的统计结果的数据量是不会多于“提取特征”之后的未处理结果的数据量的。因此,“设置灰度参考值”放在“统计相同特征的数量”之后更为合适。
2.5. 灰度参考值
2.5.1. 实现
为了克服由于环境光明暗导致的特征值的整体偏移,我们需要在被提取的范围内给出灰度参考值用以之后的识别系统的校准。为了提供人工识别的接口,这里采用的是一个心理学灰度计算公式,如公式(1)所示。公式(1)放大100倍后的结果如公式(2)所示。
(1)
(2)
由于在计算机中位运算速度为整数乘法运算的四倍,所以我们将公式(2)换算为二进制公式。在计算机中,位运算是一种二元运算符,其符号为:
,其数学意义为
。如下公式(3)为直接位运算化后的结果。因为在灰度补偿过程中仅仅需要比例关系,所以将常数分母约掉,并用Kgrey替换Vgrey。
(3)
公式(2)与公式(3)中各系数进行对比后有如下表所示(表1公式(2)与公式(3)的系数对比)。

Table 1. Coefficient comparison between formula (2) and formula (3)
表1. 公式(2)与公式(3)的系数对比
由于我们希望的偏差平均在1%左右,来更好地适配识别补偿算法,所以我们提出了公式(4)来优化偏差。具体做法是将B通道值向G、R两通道的中值拟合,在数据容量允许之内找到一个比较合适的结果。
(4)
其偏差如下表(表2公式(4)关于公式(2)的系数对比)。

Table 2. Coefficient comparison of formula (4) with respect to formula (2)
表2. 公式(4)关于公式(2)的系数对比
2.5.2. 局限
由于在《2.5.1实现》我们选择是对同一类环境做的灰度补偿公式,这就意味着:我们可以在自然光环境做明暗的灰度补偿,而对于由一种色光主导的环境向另一种色光主导的环境的转换是做不到的,因为在归一化RGB颜色模型下,不同色光主导的颜色特征其特征因子完全不同,如果要强制转换的话将导致数据转换前后的差异非常之大。
3. 原型提取结果样本
结果的文件结构见图5样本文件结构。每一组样本文件包含三个组成部分:1) 提取记录图像。如图6提取记录图像细节所示,其黄框内部分(包含红色像素点部分)为被提取部分,红色像素为提取器提取过的像素,在提取后被提取的位置被重置为了红色。2) RGB三通道谱。这组通道谱只是测试时用来观察提取结果是否覆盖到了提取范围内的主要特征。3) 特征结果文件。这个是提取模块在一次提取后最终结果的存档文件,其在浏览器中打开的效果如图7特征文件格式所示,用浏览器打开的有点在于及时XML文件没有任何格式符,在浏览器中打开也依旧会保持XML原有的树状数据格式。文件中的“src”为第一级目录,代表下级目录的数据来源于资源数据;“color”为第二级目录,代表彩色图像,由于Kinect2为体感摄像头,其中不仅有彩色图像,还有代表距离的深度图像,因此在结果文件中对这两种图像的数据加以区分,防止混淆;total代表特征总数,grey_h、grey_l、grey_a是灰度参考值,div_bit代表减色位数。以“spec_1”为例的为第三级目录,是文件的最后一级目录,用来保存颜色特征,其中的ch_B、ch_G、ch_R为颜色特征的对应BGR三通道值。

Figure 6. Extraction of recording image details
图6. 提取记录图像细节
4. 总结
本文主要是基于ROS环境设计了一款图像特征提取器模块,从工学角度出发,在不优先考虑性能的情况下设计了以实用为基本目的的颜色提取器。根据一般设计规律,本文先给出软件结构,进而进行算法实现、结果检验等问题的分析,并着重阐述了颜色提取过程和灰度参考值生成的实现和优化。本文所设计的颜色提取器对于实际应用中颜色辨识问题具有很好的实用价值。
基金项目
天津市高等学校科技发展基金资助项目(项目编号:JWK1614)。
参考文献
NOTES
*通讯作者。