图像识别,一直是计算机领域研究的热门,随着大数据的兴起,更是让图像识别中的特殊分支人脸识别如鱼得水,使得运算和样本数据不再成为系统的掣肘。那么具体来说,一个现代人脸识别系统(例如face++)是如何实现的呢?
这里我不敢妄自猜测,我仅提供我自己的实现方法,拿出来与大家一起学习和探讨:
1.首先建立目标模型,分析出目标模型的特征值,也就是在检索中所需要的KPI,我这里只是简单的列了一下,结果发现太多了,而我又太懒,写了一半没动力写下去了,人脸特征列表:
特征 |
KPI指标 |
特征描述 |
能否提取 |
特征值 |
整体 |
头发密度 |
浓密、稀疏 |
是 |
0-100 |
头发粗糙度 |
顺滑、卷毛、散乱 |
否 |
|
|
头发颜色 |
黑色、白色、棕色 |
是 |
0-255 |
|
皮肤材质 |
粗糙、细腻 |
是 |
0-100 |
|
皮肤颜色 |
棕褐色、嫩白色 |
是 |
0-255 |
|
人脸轮廓 |
圆脸、瓜子脸 |
是 |
0-10 |
|
额头 |
额头形状 |
扁平、秃头 |
否 |
|
额头大小 |
宽阔、窄小 |
否 |
|
|
额头材质 |
同整体 |
|
|
|
额头颜色 |
同整体 |
|
|
|
眼睛 |
眉毛形状 |
弯眉、剑眉、画眉 |
|
|
眉毛颜色 |
黑、褐 |
|
|
|
眼睛大小 |
|
|
|
|
眼睛形状 |
|
|
|
|
眼睛颜色 |
|
|
|
|
瞳孔大小 |
|
|
|
|
瞳孔颜色 |
|
|
|
|
眼袋大小 |
|
|
|
|
眼袋形状 |
|
|
|
|
耳朵 |
耳朵形状 |
|
|
|
耳朵大小 |
|
|
|
|
耳廓比例 |
|
|
|
|
耳垂比例 |
|
|
|
|
耳朵颜色 |
|
|
|
|
鼻子 |
鼻梁长度 |
|
|
|
鼻翼宽度 |
|
|
|
|
鼻子高度 |
|
|
|
|
鼻子纹理 |
|
|
|
|
鼻孔大小 |
|
|
|
|
鼻孔角度 |
|
|
|
|
鼻毛长度 |
|
|
|
|
嘴巴 |
嘴巴大小 |
|
|
|
嘴巴形状 |
|
|
|
|
嘴巴颜色 |
|
|
|
|
上下嘴唇比例 |
|
|
|
|
嘴唇纹理 |
|
|
|
|
嘴唇高度 |
|
|
|
|
脸颊 |
脸颊大小 |
|
|
|
脸颊形状 |
|
|
|
|
脸颊材质 |
|
|
|
|
脸颊颜色 |
|
|
|
|
下巴 |
下巴大小 |
|
|
|
下巴形状 |
|
|
|
|
下巴材质 |
|
|
|
|
下巴颜色 |
|
|
|
呵呵,确实不少,光整理KPI指标就得花1-2天吧,如果KPI列的越细,通过KPI值匹配到的人脸自然越精确。
看到这里,大家是不是已经隐约感到,人脸识别其实也不难了吧?
,错了,道理其实不难,难的就在后继的实现上。
2.提取图像的KPI指标:
提取图像中的特征区域,关键在于计算出准确的Harris角点,多年以来,不少科学家和技术人员为了使得提取更精确,提出了很多计算角点的算法,而我们不得不对这些先驱心存感激之情,正是他们的不懈努力,才使得我们今天的工作变得轻而易举。这里就可以直接使用JavaCV里提供的角点提取API,通过FaceExactor抽取类库,很方便的找到图像中的人脸。
不会这么简单吧?
的确没这么简单,真正困难的地方才刚刚开始,如果要找到人脸区域内的上述KPI,又该采用什么策略呢?在这里据我所知,业内是没有很好的解决方案的,通常他们都是使用算法自动分类的手段。
什么意思呢?也就是将图像矩阵的二维数据,通过机器学习,从海量的样本数据中找到规律,并自动将数据包分类。
这里就有必要提一下时下比较流行的“支持向量机模型”,“支持向量机”就是将低维数据转换为高维数据,发现数据的规律,并分类。
请注意:以上的这种手段是从纯数学的角度找到的解决方案,并不符合人类识别物体的思维习惯,也就是说程序自动划分的图像的特征数据包,对人类来说,是没有任何意义的!
好了,问题来了:
怎样让取得的图像碎片数据包既能准确表述图像的特征规律,又有语法上的意义?
这里,我的解决方案就是人工干预:将图像碎片数据包以列表的形式在后台呈现出来,在Lucene的检索字段中预先建立好了可以容纳KPI的字段,比如:眼睛大小、鼻梁长度等。
每次样本数据被“支持向量机”分类后,便让管理员手工在后台进行标注,也就是给数据包打标签
那么,紧接着,大家会问:
这样现实吗?这么海量的数据,人工操作到什么时候?
幸运的是,我们并不需要重复标注,对于有意义的图像碎片包,我们仅仅只需标注一次即可,下次相似的图像碎片就会自动分配到此标签下,而管理员仅需剔除完全错误的碎片包即可,也就是说,系统运行后期,管理员只是在做“内容检查”
4.建立人脸识别的金字塔模型
好了,一切看似ok了,为什么还要做第四步,这不是有点多余吗?
呵呵,还是那句话,没这么简单。人脸识别系统最重要的也是系统运行的速度,通常数据都是TB为单位的,再通过CBIR将图像分解为特征词包, 那数据量会成倍增长,如果没有科学的架构,再好的算法也是望洋兴叹!
我们这里先暂时设置金字塔的层次为3层,第一层只有三个特征值,第二层有6特征值,第三层包含了所有特征值
如下表所示:
头发颜色 |
人脸轮廓 |
眼睛形状 |
|||||||||
头发材质 |
头发粗糙度 |
皮肤材质 |
皮肤颜色 |
眉毛形状 |
眼睛大小 |
||||||
头发 密度 |
头发 粗糙 度 |
... |
... |
脸颊 大小 |
脸颊 形状 |
... |
... |
... |
... |
... |
... |
选择KPI指标时需要比较小心,上一层的KPI必须能涵盖下一层的KPI,否则查找特征就容易丢失。
每次系统发起查找,实际只用第一层的KPI进行匹配,再从匹配的结果集里用第二层KPI进行匹配,依次类推,直到找到最匹配的结果。
5.性能及结果准确度测试
这里的性能结果和准确度,只能在系统真正实现了以后提供给大家了,在这里就不写了。
但是有一点是可以肯定的:系统的KPI设置的越合理,则系统查询越快速越准确!
在这样的体系结构下,打造一个可靠的人脸识别系统是完全有可能的!