• 虹软AI 人脸识别SDK接入 — 性能优化篇(多线程)


    大家都嫌公司以前使用的刷卡门禁太麻烦,正好借这个机会开发一个人脸识别的门禁系统,采用的SDK是虹软公司开发的,接口调用比较简单。

    一、虹软SDK接口性能

    在配置为i5-7400 、16G内存的PC上测试性能如下:

    1.FT 单次3ms左右

    2.FD 单次10ms左右

    3.FR 单次170ms左右
    二、业务层需要解决的问题

    1.FT和FR单次性能相差较大,速度不匹配

    2.FT支持多人脸,单次检测人脸较多,而FR只支持单人脸

    3.视频帧单次处理可能会超过帧间隔时间

    三、优化方案

    人脸识别过程包括三个步骤,检测人脸、人脸特征提取、特征匹配,以人脸识别的门禁系统为例,主要步骤获取视频帧、检

    测视频帧人脸、提取特征、特征匹配,门禁系统对于实时性要求比较高。

    流程图大概如下:

    下面说下开发过程中多线程方面的优化点。

    1. 获取视频帧

    摄像头视频的帧率正常在25~30帧左右,并且一般的视频帧的分辨率为1280x720,当然有的摄像头可以达到更大的分辨率,

    但是经过测试多款摄像头,发现分辨率设置过大会导致获取视频帧的过程中卡顿。并且分辨率适中,会提升后面的FT的速度。获取视频帧的操作是在主线程进行的。

    lock_guard<std::mutex> locker(g_CameraMutex);
    
    if (m_camera->getFrame(m_curFrame))
    {
    return;
    }
    
    ftProcessor->faceDetect(m_curFrame, m_resizeImage);
    

      

    2. 人脸识别处理优化

    采用了获取视频帧和FT串行的方式,需要保证从获取视频帧一直到处理完成,必须在帧间隔时间内(帧率为25时,在40ms左右),否则可能会出现卡帧的情况。经测试,获取视频帧和FT串行的单次时间在帧间隔时间内,因此采用串行的方式。
    FT支持多人脸检测,我将检测最大人脸数设置为5,所以在极限状态下,人数较多的话,待识别的人数可能一直维持在5人,这就需要提高FR的有效识别率。

    FR使用了一个自定义threadsafe_queue简化多线程数据同步操作,在FT中将需要进行FR的人脸框以及对应的视频帧和人脸框的trackid push_back到threadsafe_queue中,FR线程从中取人脸框信息和视频帧,做提取特征和特征匹配处理。

    ![](https://oscimg.oschina.net/oscnet/07c6d7e96b3f93039e5a56edefee1c2b27f.jpg)

    我从以下几个点优化人脸识别效率:

    a.增加FR线程数量。
    对于我来说,开线程池的方式可行性并不太高。首先机器的内核数限制的线程数,动态增加线程数听起来不错,但是门禁使用的一体机毕竟跟开发机器不一样,性能限制太多,并且线程切换和数据同步都会更加复杂。但是为了提高FR的识别速度,我最终开了两个FR线程,经测试,在i5-7400T 8G内存 配置的机器上,CPU大概处于40%左右。

    b.提高FR识别效率
    优化FR识别效率要求FR做到每次识别都是有效的,也就是说FR不做垃圾帧的处理。

    1)每次在获取到人脸后,判断是否与前一帧检测到的人脸结果属于同一个人(通过trackid判定,这一部分留到后面的文章说明,敬请期待)。如果某个人脸框首次出现,或者如果某个trackid对应的人脸框仍未识别成功,都需要做FR操作。

    ![](https://oscimg.oschina.net/oscnet/4c63cf8ee2a9f18c2dc83249aae61ecb3a3.jpg)

    case FTSucceed:
    case FRFailed:
    {
    newFaceInfo.faceStatus = FRWaiting;
    FRParam frParam = { 0 };
    frParam.curImageInfo = m_curImageInfo;
    frParam.faceInfo.faceOrient = newFaceInfo.faceOrient;
    frParam.faceInfo.faceRect = {
    newFaceInfo.faceRect.wleft,
    newFaceInfo.faceRect.wtop,
    newFaceInfo.faceRect.wright,
    newFaceInfo.faceRect.wbottom };
    
    frParam.trackid = newFaceInfo.trackid;
    
    m_frParamsQueue.push(frParam);
    }
    

      

    当某个trackid对应的人脸已经在等待或者在做FR的时候,在后面检测到的该trackid对应人脸将不再做FR,一直到FR检测结果出来以后,再做处理。

    case FRProcessing:
    case FRWaiting:
    {
    //default color
    }
    break;
    

      


    2)识别成功后,同样将该trackid所对应的人脸都设置为识别到的人,这样下次就不需要再次做FR,不会浪费FR的时间片。
    3)每次在从threadsafe_queue获取的待处理的人脸框、trackid和视频帧时,都检测该trackid是否已消失,如果消失,就不做FR,因为拿到的结果毫无用处,直接丢弃。

    std::lock_guard<std::mutex> locker(m_faceInfoListMutex);
    //找到对应的trackid 对应的人脸,设置为FRProcessing
    auto iter = find_if(m_prevFacesRes.begin(), m_prevFacesRes.end(), [=](const FaceInfo& lhs)
    {
    return lhs.trackid == frParam.trackid;
    });
    
    if (iter != m_prevFacesRes.end())
    {
    iter->faceStatus = FRProcessing;
    }
    else
    {
    //找不到 就不用做FR了
    continue;
    }
    

      

    `

    好了,这次就说到这,大家有什么问题的话,可以留言,谢谢。
    参考链接:
    1.trackid 介绍:https://www.jianshu.com/p/4ae90634a79e

  • 相关阅读:
    算法两则
    windows XP 神key
    mysql空间型数据使用python executemany批量插入报错
    关于集合的相似度测量方法
    读取经纬度坐标并存储为字典格式,即key为ID,value为轨迹点
    ubuntu下安装软件时报错解决:Unmet dependencies. Try 'apt-get -f install' with no packages
    ubuntu环境下pycharm编译程序import包出错:ImportError: dynamic module does not define init function (init_caffe)
    linux Ubuntu14.04 make编译文件报错:No rule to make target `/usr/lib/libpython2.7.so', needed by `python/_pywraps2.so'. Stop.
    U盘安装Ubuntu14.04&配置远程win10远程连接
    解决:error LNK1169: 找到一个或多个多重定义的符号
  • 原文地址:https://www.cnblogs.com/Zzz-/p/10837896.html
Copyright © 2020-2023  润新知