网站首页  词典首页

请输入您要查询的论文:

 

标题 基于虹软算法的多人脸目标识别系统实现
范文

    李殊哲 丁德红

    

    

    

    摘要:为实现多人脸目标的识别,使用FileWatcher监测文件夹下新生成的图片,从这些新的图片中,利用改进后的虹软算法实现人脸检测,再提取其人脸特征值,最后与注册过的人脸特征值进行对比。该系统采用.Net Frame框架,简化了原demo中对识别没有帮助的数据处理程序,纠正了代码中导致内存泄漏的函数,实现了多线程并发的多目标识别。

    关键词:虹软算法;多人脸目标;文件监控

    中图分类号:TP311.1 ? ? ?文献标识码:A

    文章编号:1009-3044(2020)31-0215-04

    1 背景

    人脸识别作为一种新兴的生物特征识别技术,依据人的面部特征对身份进行自动鉴别技术[2]。随着我国计算机技术的不断发展,我国在这方面也取得了较好的成就,国家863项目“面像检测与识别核心技术”通过成果鉴定并初步应用,就标志着我国在人脸识别这一当今热点科研领域掌握了一定的核心技术。

    文献[4]在低像素人脸识别检测的过程中,首次将单一图像分辨率重建的SRCNN算法用于提高人脸检测率,优化改进了对异常值和噪声的处理,并将MTCNN、S-LBPH以及SRCNN算法结合应用于考勤中取得了较高的考勤率。使用S-LBPH算法克服了传统LBPH算法不能很好区分异类间特征的问题。文献[5]中通过对视频图像多人脸并行检测算法和PCA多人脸识别算法的改进大大提高了单幅人脸的检测效率,充分利用了视频图像帧序列直接的间接信息,在一定条件下提高了人脸识别的正确率,通过新建ORL人脸库进行检验正确率高达97.62%。但是,文中也提到该算法虽然在速度方面有明显的优势,但在处理远处人脸或遮挡人脸时识别率有待提高。文献[6]中作者将多人脸识别应用到反恐维稳、案件侦破、服务民生等公共安全领域。并提到在进行多人脸识别算法应用平台建设过程中,我們不仅要注意技术的创新,也需要将技术于业务有机结合才能真正的服务于社会。

    目前我国各大企业都给出了自己的免费人脸识别算法。虽然,各企业都尽可能地简化了他们的算法接口,但由于其本身的复杂性,大多数人在使用时仍然会遇到大量的问题。而且他们的代码在使用时也并不完全安全,例如:某些代码在使用时会造成内存泄漏、某些对象不可以多线程调用。这些问题官方在文档中并没有标识,如果要开发者自行摸索通常需要很长时间。因此,我们撰写了此文,总结一年以来我们使用虹软算法开发的经验,提醒后续研究者避免相同的错误。

    2 系统整体设计

    如下图1,该程序的设计类图如下:

    Form类,这个类表示的是系统中的所有界面类,根据行业惯例简化类图,我们将他们统一放在一个类中表示。

    DBOparetor负责提供数据库操作有关的接口,避免类与数据库直接接触,也可以减少访问数据库所需编写的代码量。这个类与Loader的区别在于它包含的最底层的数据库操作,而Loader则是将他的操作组合起来再封装一次以简化外部模块调用时的复杂度。

    Comparer类负责将照片与数据库中的特征码比对,其结果会传回到调用模块。这个类的技术难点在于识别所需的计算量巨大,该类必须大量采用多线程与异步的技术来提升识别速度与避免堵塞UI线程。

    FileWatcher类负责调用FileSystemWatcher来控制Comparer对图像的识别。FileSystemWatcher是微软提供给开发者的文件监测类,它可以监控指定文件夹内一个甚至多个指定类型或指定名称的文件的生成、修改和删除。它通过Windows的消息机制来实现,我们只需要编写回调函数并订阅其相应事件设定好响应功能就可以。对于这个类的介绍在下面还会详细描述。我们的程序使用这个类监控文件夹内的照片类型文件的生成,这样一旦有照片放入文件夹内就会调用执行函数让Comparer类对其进行扫描。此外我们还可以一些异常处理的方法来提高程序的可靠性。

    Loader类负责从数据库加载数据。由于在该程序中可能需要在多个表之间查询,而且还需要有多种查询模式,因此我们将加载单独作为一个功能集成了起来。当外部模块需要查询数据时不会直接调用DBOparetor类,而是统一使用Loader来获取数据。

    Submiter类负责提交数据。在Comparer类完成数据比对之后,主控模块通过该类来将数据传至Web服务器或数据库服务器。Submiter会直接与DBOparetor交互而不经过Loader,因为他所需要的数据库操作并不是获取信息而时提交信息,但是目前Submiter已经不会直接向数据库提交信息了。这是早期程序提交考勤记录的方法。那时我们的系统还没有建立专门管理考勤数据Web服务器,现在有了Web服务之后比对程序的考勤记录会提交给Web服务器由它来负责管理数据库。本文仅讨论对比算法的使用Web服务器的相关事项不再详细介绍。

    3 文件监控模块

    要进行人脸识别就必须有输入的图片,本系统通过调用微软提供的FileSystemWatcher类来监控文件夹下的图片文件。它的主要作用是Listens to the file system change notifications and raises events when a directory, or file in a directory, changes[1].该类可以监听指导文件夹内的五种操作,而我们通过监控文件夹内图片文件的生成操作,一旦有新的图片文件进入文件夹就会启动识别程序对其进行识别。

    FileSystemWatcher有六个事件,其中五个是当指定文件发生某种操作时的响应事件,而Error则是FileSystemWatcher本身发生异常时的响应事件。通过这五个事件我们可以顺利的完成对指定文件的所有活动进行处理,当然在本系统里只用到了Created事件。

    上面我们讲解了如何指定响应函数和要响应的文件操作,接下来读者可以通过我们的监测开始函数及其注释来了解FileSystemWatcher的监控目标的设置。如下FileWatch中的开始函数。

    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]

    public void WatcherStart(string StrWarcherPath, string FilterType, bool IsEnableRaising, bool IsInclude)

    {

    Task.Run(() =>

    {

    watcher = new FileSystemWatcher();

    watcher.Filter = FilterType;

    watcher.IncludeSubdirectories = IsInclude;

    watcher.NotifyFilter = NotifyFilters.FileName;

    watcher.Path = StrWarcherPath;

    watcher.Created += Watch_created;

    watcher.Error += WatcherError;

    watcher.EnableRaisingEvents = false;

    watcher.EnableRaisingEvents = IsEnableRaising;

    });

    }

    开始前我们需要一些系列的属性设置,包括:指定文件夹、选定监听函数等。这里需要额外强调的是函数上方需要添加权限注解,否则监控可能会无法开启。

    Watch_created就是Created事件觸发时对应的相应函数,它的代码如下:

    private void Watch_created(object sender, FileSystemEventArgs e)

    {

    List indexes;

    Task> t = compare.GetIndex(image, MainWindow.pEngine);

    FileInfo fileInfo = new FileInfo(e.FullPath);

    indexes = t.Result;

    foreach (int index in indexes) {

    if (parent.stus[index].time == null || DateTime.Now - parent.stus[index].time >= parent.TimeSpan)

    {

    parent.stus[index].time = DateTime.Now;

    _ = parent.ShowName(parent.stus[index].name);

    parent.Log(parent.stus[index].name + "到勤");

    });

    }

    else{

    parent.Log(parent.stus[index].name + "五分钟内多次出现");

    }

    }

    在省略一部分用于处理异常的函数后可以看到在这个函数中,我们将调用对比模块对其进行识别。由于C#的事件机制本身是多线程模式的,所以我们可以直接在函数中等待识别结果,而不用担心阻塞主线程。获取到照片的结果时,我们要对结果进行判断,如果该结果五分钟内未被识别到过判断为有效考勤,如果五分钟内出现过就判断为无效考勤。

    4 数据库设计

    在比对照片前首先需要提取作为标准的特征码,这些特征码我们将它们作为记录保存在数据库中。由于比对程序的数据库十分简单,因此在数据库设计时做了说明但没有设计具体设计,这里做一个补充说明。比对子系统所用到的数据只有脸部特征。其数据表的具体结构如下表。

    程序开启时,主控模块会调用Load类将这些数据加载到内存中。在之后的比对过程中Comparer类直接访问内存来获取特征码。

    5 比对算法介绍

    本系统采用的人脸识别算法为虹软的免费算法,其具有离线、快速、识别率高等特点。在当时选择算法时主要考虑到的就是离线或在线的问题。由于我们的系统要对密集人群进行考勤,所以在线方式的考勤势必大大增加网络压力,而市面上免费又离线的人脸识别算法只有虹软,因此我们选择了他们的算法。

    5.1 Entity

    这个文件夹中包含了程序中将会使用到的实体类,目前这文件夹中只有一个类ImageInfo。这个类可以保存图片的宽高等信息,其中还有一个IntPtr指针用于保存照片信息。因为该sdk是有C++编写,因此在使用时参数常常要以非托管内存的形式传入,将图片转化为这个类之后可以方便sdk对其进行识别

    5.2 SDKModels

    这个文件夹较为重要是一些sdk所用到数据结构。

    这里面比较常用的有ASF_MultiFaceInfo类,用于保存多人脸识别后的函数返回值。ASF_SingleFaceInfo类,用于保存单人脸识别后的识别信息。值得一提的是,这里的函数返回值并不会直接是这里的类,因为虹软的算法原本是由C++编写的,实际上的返回值是一个C++的结构体。C++的结构体返回到C#中将会是一个IntPtr指针,虹软还另给了函数将这些IntPtr指针转化为这些实体类。

    这个文件中的实体类与Entity十分相似,但这个文件夹中的实体类是对应着sdk算法中的实体类的。也就是动态库里C++结构体的C#表达形式。

    5.3 SDKUtils

    这个文件夹中保存的是虹软识别算法的函数入口。这个文件夹中只有一个ASFFunctions类,虹软通过DllImport注解将dll中由C++编写的函数的入口导出到这个类中。如图5是一个函数导入的语法示范,是将名为ASFActivation的函数从dll中导入。

    ///

    /// 激活人脸识别SDK引擎函数

    ///

    /// SDK对应的AppID

    /// SDK对应的SDKKey

    /// 调用结果

    [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)]

    public static extern int ASFActivation(string appId, string sdkKey);

    这样这些原本由C++编写的算法就可以在这个类中被调用。这个文件夹中包含了所有虹软sdk的识别函数。下面我们介绍三个特别重要的函数。这个三个函数在识别的过程中起到了非常重要的作用。

    ASFDetectFaces函数,这个函数用于监测是否由人脸。其会通过out参数的形式返回一个对应ASF_MultiFaceInfo的IntPtr指针,拿到这个返回值后我们就可以得到图片中的人脸个数和具体位置、区域。

    ASFFaceFeatureExtract函数用于提取某个区域的人脸特征。这个函数可以通过out参数来返回人脸特征码以供后续的比对函数使用。

    ASFFaceFeatureCompare比对函数,这个函数通过out参数返回一个float类型的值,这个值指示了两个特征码之间的相似度。

    5.4 Utils

    Utils文件夹中主要保存了处理照片信息的类和处理非托管内存的类。这些类可以将照片和IntPtr指针分别处理成易于操作的ImageInfo类或SDKModeles中的类。在识别中主要起到处理数据的作用。

    Utils与SDKUtils的区别在于,SDKUtils中包含的是sdk中的函数,在C#中只是引入而没有源码,这些函数往往直接与识别相关。而Utils则是一些使用C#编写的代码,可以直接在文件中看到它们的实现方式,这些函数通常是做数据处理起到辅助识别的作用。

    6 人脸检测

    在人脸检测时需要有三个步骤,第一步处理照片,第二步提取人脸区域,第三步提取区域特征码,第四步比对特征码。

    处理照片:程序通过FileSystemWatcher检测到有文件生成时会得到文件的绝对路径,然后程序会通过该路径得到相应的图片。由于比对算法不支持某些比例下的照片,得到照片之后程序会进行一个宽高比的调整将宽度统一改为4的整数倍。然后通过读取图片文件,将文件里的信息读取到内存之中。由于该算法本来是由C++编写,所以这里需要将图片信息读取到非托管内存中。到这里图片数据的处理就结束了。

    提取特征码:对照片数据的处理完成后就可以调用ASFDetectFaces函数对照片进行照片中的人脸部分进行划分,识别出人脸在照片中的具体位置,在官方给出的demo中没有这一步骤,但是据我们的测试这样做可以有效地降低非本人照片的识别率,一定程度上的增加总体识别率。

    提取人脸区域特征码:调用ASFFaceFeatureExtract函数对指定区域进行特征码的提取。

    比对特征码:使用ASFFaceFeatureCompare将特征码与所有数据库中的已有特侦码进行比对得到相似度最高的人脸。

    7 结束语

    本文详细描述了如何使用微软的FileSystemWatcher类对指定文件夹下的图片文件进行监控,并在新文件出现时使用虹软的人脸识别算法识别对比。虽然由于其算法免费使用但不开源导致我们能施展的空间有限,但是我们还是在这种情况下,利用有限的条件对识别的速度和准确率进行改进。

    1)在数据处理方面,我们精简了Utils文件夹中的数据处理代码,在不影响识别率的情况下将速度提升了5-6倍;此外在实际使用时,我们发现官方给出的CutImage函数会造成内存泄漏问题,请读者在自己编程时务必自行编写裁剪函数。

    2)通过识别前的处理事先得到人脸的进一步位置,将出现人脸的位置图片进一步裁剪下来,再提取特征值。这样减少了特征值的提取范围,经测试这一操作减少了误判的概率在一定情况下有效提升了识别率,而且识别的速度也有一定的提升。

    人脸识别技术已经成功应用到金融、军工等多个领域, 行业发展优势明显[3]。而本系统的代码实现简洁、高效,并且可以实现多线程识别(论文中没有提及,但是实际上现有代码中已经实现),读者可以这些代码和讲解为基础结合类名进一步理解SDK接口,将人脸识别广泛地应用于各个领域。

    参考文献:

    [1]微软API参考文档[EB/OL].[2020-05-14].https://docs.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=netcore-3.1.

    [2] 李彬,曲寒,冰靳薇.浅谈人脸识别技术在智能视频监控中的应用与发展趋势[J].中国安防,2011(3):50-53.

    [3] 耿艳萍.浅谈人脸识别技术及其应用[J].科学之友,2011(7):131-133.

    [4] 张玉云.基于MTCNN和S-LBPH算法的多人脸识别在课堂考勤中的应用[D].成都:西南交通大学,2019.

    [5] 程战员.面向智能视频监控的多人脸识别算法研究[D].武汉:武汉理工大学,2013.

    [6] 李仁杰,曾鵬,张龙.多人脸识别算法和大数据融合技术在公共安全领域的应用研究[C].2019年全国公共安全通信学术研讨会优秀论文集,2019.

    【通联编辑:谢媛媛】

随便看

 

科学优质学术资源、百科知识分享平台,免费提供知识科普、生活经验分享、中外学术论文、各类范文、学术文献、教学资料、学术期刊、会议、报纸、杂志、工具书等各类资源检索、在线阅读和软件app下载服务。

 

Copyright © 2004-2023 puapp.net All Rights Reserved
更新时间:2025/3/21 14:28:19