0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于EAIDK的人脸算法应用-源码解读(2)

电子设计 来源:电子设计 作者:电子设计 2020-12-10 21:14 次阅读

1 本期内容介绍

上一期介绍了基于EAIDK的人脸算法应用,本期从应用角度,解读一下该案例源码。
本期案例源码解读,主要从源码目录结构、配置文件、模型目录、源码流程、重点源码文件等进行解读。

本期源码解读目标:

1. 让EAIDK-310开发者对EAIDK-310环境更加熟练
2. 熟悉EAIDK-310人脸识别案例源码
3. 方便开发者使用vision.sdk的调用流程,为二次开发做指引参考

2 目录结构介绍

ftp://ftp.eaidk.net/EAIDK310/_Source/eaidk310/_face/_package/获取源码包后,直接解压后得到eaidk310_face_package文件夹,文件夹内容如下图所示:

eaidk310_face_demo.zip解压后,源码包整体目录结构如下:

doc目录:指文档目录,包含Vision.Face SDK手册,Vision.Face SDK人脸算法Q&A手册。其中Vision.Face SDK手册,详细介绍了人脸算法的各个API接口,本案例人脸应用调用的接口全部在该文档中有介绍。

face-sdk目录:vision.sdk人脸算法库(libface.so

eaidk310/_face/_demo.zip:eaidk310人脸推广案例的源代码包,解压后的目录截图如下:

build-eaidk/_visual/_embedded-Desktop-Debug:编译目录和运行目录,里面有demo运行时必需的文件和目录,比如配置文件demo.conf,models模型目录。

eaidk/_visual/_embeded:源码目录,案例实现的源代码都在该目录下,下文也将重点介绍该目录下源码文件。

libs:本案例依赖的vision.sdk人脸库,内容与上文提到的face-sdk目录内容一致。

3 配置文件&模型文件

demo.conf,该文件必须在案例程序的运行的当前路径,已配置好默认的参数,理解即可。

VideoWidth=1280      -->采集视频图像的宽
VideoHeight=720      -->采集视频图像的高
Scale=1              -->采集视频图像的缩放比例
MinFaceSize=40       -->人脸算法的最低像素要求
Clarity=200          -->人脸算法的最低清晰度要求
FaceAngle=0.4        -->人脸算法的最低角度要求
ThresHold=0.7        -->人脸识别的最低阈值要求
UseApi=0             -->人脸算法的调用策略
Dbsize=10000         -->人脸库的最大存储人脸数
RegisterMethod=0     -->人脸注册策略
FacePicturePATH=./models/faces/   -->人脸存储本地路径

模型目录
mfn.tmfile,mobilefacenet人脸识别模型文件
det1,det2,det3.tmfile,人脸检测模型文件
face_attr.tmfile,人脸属性模型文件

4 流程介绍及源码解读

4.1 实现流程

整体流程结构如下:

4.2 流程与源码解读

下面我们对此案例中的重要&核心的代码内容进行解释,为读者提供参考,方便读者了解vision.sdk算法应用。

4.2.1 mainwindow.cpp

程序从main函数入口,在main中创建显示窗口,具体显示内容在mainwindow.cpp中实现。mainwindow.cpp源程序中主要实现2个功能:

    1. UI布局
    2. 图像采集

mainwindow.cpp源程序包含构造函数、updateImage函数、open_camera函数等重要函数。

4.2.1.1 构造函数

所有对象创建时,都需要初始化才可以使用,而构造函数就是用于给对象进行初始化,在堆内存中开辟出一个空间来存放建立的对象并赋初始值。

    /* connects */
    connect(&theTimer, &QTimer::timeout, this, &MainWindow::updateImage);

    connect(ui->face_attr_2, SIGNAL(clicked(bool)), this, SLOT(convert_to_face_attr()));
    connect(ui->face_rec_2, SIGNAL(clicked(bool)), this, SLOT(convert_to_face_rec()));
    connect(ui->rb_face_track, SIGNAL(clicked(bool)), this, SLOT(convert_to_face_track()));

updateImage,是theTimer对应的槽函数,每隔33ms调用一次,该函数是mainwindow.cpp文件中最重要的函数,它包含图像的显示、人脸算法处理结果的显示。
其他connect均为显示界面的各个按钮及其对应槽函数:

    /* regist related */
    connect(ui->regist, SIGNAL(clicked(bool)), this, SLOT(user_regist()));
    connect(ui->cancel, SIGNAL(clicked(bool)), this, SLOT(user_cancel_regist()));
    connect(ui->ok, SIGNAL(clicked(bool)), this, SLOT(user_save_regist()));
    connect(ui->ok_2, SIGNAL(clicked(bool)), this, SLOT(get_user_name()));
    connect(ui->cancel_2, SIGNAL(clicked(bool)), this, SLOT(back_to_face_rec()));
4.2.1.2 updateImage函数

updateimage函数是UI显示的核心函数,每隔33ms调用1次,填充视频窗口的区域。

void MainWindow::updateImage()
{
    ui->label_diku->clear();
    ui->label_diku_2->clear();
    cam->videoCapL>>cam->srcImageL;

cam->videoCapL>>cam->srcImageL;该行功能是获取摄像头数据并存入srcImageL变量。

updateimage函数下调用了face_rec_enabledface_attr_enabledface_track_enabled等函数

face/_rec/_enabled,表示打开人脸识别功能,该{}内表示人脸识别的代码处理部分。
人脸识别处理部分:

if(face_rec_enabled)
{
       algThd->setUseApiParams(0);
       algThd->face_rec_label = true;
       cv::resize(cam->srcImageL, ResImg, ResImgSiz, CV_INTER_LINEAR);
       algThd->sendFrame(ResImg, cam->srcImageL);
       Mface face_result = algThd->getFace();

获取人脸的结果后,line函数对图像中的人脸画框,label_diku_2对人脸图像做show(显示)处理。

       if(face_result.drawflag && strcmp(face_result.name, "")!=0 && strcmp(face_result.name, "unknown")!=0){
           if(access(facepath, F_OK) < 0)
           {
               printf("%s:%d %s not exist./n", __func__, __LINE__, facepath);
               return;
           }

           int x = face_result.pos[0].x;
           int y = face_result.pos[0].y;
           int w = face_result.pos[0].width;
           int h = face_result.pos[0].height;
           line(cam->srcImageL, cvPoint(x, y), cvPoint(x, y + 20), cvScalar(0, 255, 0, 0), 2);
           line(cam->srcImageL, cvPoint(x, y), cvPoint(x + 20, y), cvScalar(0, 255, 0, 0), 2);

           line(cam->srcImageL, cvPoint(x + w - 20, y), cvPoint(x + w, y), cvScalar(0, 255, 0, 0), 2);
           line(cam->srcImageL, cvPoint(x + w, y), cvPoint(x + w, y + 20), cvScalar(0, 255, 0, 0), 2);

           line(cam->srcImageL, cvPoint(x, y + h), cvPoint(x + 20, y + h), cvScalar(0, 255, 0, 0), 2);
           line(cam->srcImageL, cvPoint(x, y + h), cvPoint(x, y + h - 20), cvScalar(0, 255, 0, 0), 2);

           line(cam->srcImageL, cvPoint(x + w, y + h), cvPoint(x + w, y + h - 20), cvScalar(0, 255, 0, 0), 2);
           line(cam->srcImageL, cvPoint(x + w, y + h), cvPoint(x + w - 20, y + h), cvScalar(0, 255, 0, 0), 2);

           Mat diku = cv::imread(facepath);
           cvtColor(diku, diku, CV_BGR2RGB);
           QImage imagel = QImage((uchar*)(diku.data), diku.cols, diku.rows, QImage::Format_RGB888);
           ui->label_diku->setPixmap(QPixmap::fromImage(imagel));
           ui->label_diku->resize(imagel.size());
           ui->label_diku->show();

           cv::Mat realtime_face;
           cam->srcImageL(Rect(face_result.pos[0].x, face_result.pos[0].y, face_result.pos[0].width, face_result.pos[0].height)).copyTo(realtime_face);
           cvtColor(realtime_face, realtime_face, CV_BGR2RGB);
           cv::resize(realtime_face, realtime_face, Size(120, 120), CV_INTER_LINEAR);
           QImage imagel2 = QImage((uchar*)(realtime_face.data), realtime_face.cols, realtime_face.rows, realtime_face.cols*realtime_face.channels(), QImage::Format_RGB888);
           ui->label_diku_2->setPixmap(QPixmap::fromImage(imagel2));
           ui->label_diku_2->resize(imagel2.size());
           ui->label_diku_2->show();

face_attr/enabled,表示打开人脸属性功能,该{}内是人脸属性演示的代码部分。
人脸属性处理部分:

else if(face_attr_enabled)
{
       algThd->setUseApiParams(1);

       cv::resize(cam->srcImageL, ResImg, ResImgSiz, CV_INTER_LINEAR);
       algThd->sendFrame(ResImg, cam->srcImageL);
       Mface face_result = algThd->getFace();

face/_track/_enabled,表示打开人脸跟踪功能,该{}内是人脸跟踪的处理部分。
人脸跟踪处理部分:

else if(face_track_enabled)
{
       algThd->setUseApiParams(6);

       cv::resize(cam->srcImageL, ResImg, ResImgSiz, CV_INTER_LINEAR);
       algThd->Tracker(ResImg,cam->srcImageL);
       cv::resize(cam->srcImageL, ResImg, ResImgSiz, CV_INTER_LINEAR);
       algThd->sendFrame(ResImg, cam->srcImageL);
       Mface face_result = algThd->getFace();

上面人脸识别、人脸属性、人脸跟踪的处理部分都用到了setUseApiParams()sendFrame()getFace()函数:

setUseApiParams(),设置算法处理策略,0表示做人脸识别功能,1表示做人脸属性功能,6表示做人脸跟踪功能;
sendFrame(),将采集到的图像发送到算法线程进行处理;
getFace(),获取返回的人脸数据。当mainwindow采集图象时,调用sendFrame()函数,把采集到的数据传送给循环处理的线程,并通过getFace()函数获取结果并显示。
4.2.1.3 open_camera函数

open_camera是用来采集USB摄像头视频的函数,获取的图像用来输入给人脸算法函数。其中参数0表示USB摄像头的设备节点(/dev/video0),当该节点不存在或者非usb摄像头设备时,采集图像会失败。

if(cam->videoCapL.open(0))
{
    cam->srcImageL = Mat::zeros(cam->videoCapL.get(CV_CAP_PROP_FRAME_HEIGHT), cam->videoCapL.get(CV_CAP_PROP_FRAME_WIDTH), CV_8UC3);
    theTimer.start(33);
}

4.2.2 AlgThread.cpp

mainwindow类的构造函数中,line131创建人脸算法处理的对象algThd,并调用start()函数开启人脸处理线程,其内容的实现在AlgThread.cpp中。人脸算法的流程是输入图像、深度学习类型人脸算法处理、返回结果、窗口显示。

    ConfigParam param;
    LoadConfig(param,false);

    algThd = new AlgThread(param);
    algThd->start();
    ResImgSiz = cv::Size(NORMAL_FRAME_W, NORMAL_FRAME_H);

AlgThread.cpp源程序包含线程函数run,来实现人脸跟踪/人脸检测/特征值提取/人脸特征值比对/人脸注册等核心功能。

4.2.2.1 线程函数run

线程函数run()是一个while(1)循环函数,param.useapi为0时表示人脸识别,为1时表示人脸属性,为6时表示人脸跟踪。

void AlgThread::run()
{
    static unsigned long long tv_start, tv_end,t0,t1;
    float feature0[FEATURE_SIZE];
    float feature1[FEATURE_SIZE];
    float score;

    for (int i=0;i lck(m_mtx_reg);
        getframe(mat);
        getSrcframe(grayframe);
        if (mat.empty()) continue;
        int face_recognize_return_value = FaceRecognize(mat,grayframe,0);;++i)>

其他重要的函数如下,用黄色背景标注:
FaceRecognize,人脸识别函数
GetFeature,获取特征值函数,提取检测到的人脸的特征值
Register,人脸注册,特征值存入数据库函数
CompareFaceDB,人脸比对函数

        int face_recognize_return_value = FaceRecognize(mat,grayframe,0);

        if(0x0b == param.useapi)//liveness do not need compare feature
        {
            continue;
        }
        printf("%s %d face_recognize_return_value:%d/n", __FUNCTION__, __LINE__, face_recognize_return_value);
        if(face_recognize_return_value != SUCCESS){
            printf("%s %d face_recognize fail.../n", __FUNCTION__, __LINE__);
            t0=tv_start;
            if (param.useapi==2) {
                //gettimeofday(&tv_end, NULL);
                //tv_end = get_ms();
                //m_fps = (float)1000.0 /(tv_end.tv_sec * 1000 + tv_end.tv_usec / 1000 - tv_start.tv_sec * 1000 - tv_start.tv_usec / 1000);
            }
            continue;
        }
        else
        {
            printf("%s %d face_recognize success.../n", __FUNCTION__, __LINE__);
        }
        if(1 == param.useapi)
        {
            continue;
        }
        ret=faceapp::GetFeature(mFace,feature1,&res);
        if (ret!=SUCCESS) {
            printf("%s %d get feature fail..../n", __FUNCTION__, __LINE__);
            t0=tv_start;
            if(ret==ERROR_BAD_QUALITY)
                m_face.nam;
            continue;
        }

        if(regist_label){
            Register(mat, feature1, (char*)reg_name.c_str());
            regist_label = false;
            reg_name = "";
        }

        if(face_rec_label){
            ret = CompareFaceDB(feature1);

vision.sdk的使用,流程是初始化->人脸检测->人脸特征值提取->人脸注册->人脸比对函数使用,如上函数调用顺序基本也是vision.sdk的调用顺序:

5 总结

该案例解读文档主要主要从源码目录结构、源码简要流程、重点源码函数几个方面进行了解读和介绍,并按照功能实现流程顺序,介绍了基于EAIDK的人脸识别案例源码中的重要函数及其实现的功能,并贴出实际使用代码,方便开发者理解,为开发者进行二次开发提供参考。

审核编辑 黄昊宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 算法
    +关注

    关注

    23

    文章

    4629

    浏览量

    93305
  • 人脸识别
    +关注

    关注

    76

    文章

    4015

    浏览量

    82281
  • 深度学习
    +关注

    关注

    73

    文章

    5512

    浏览量

    121503
收藏 人收藏

    评论

    相关推荐

    新唐科技基于NuMaker-M55M1平台的人脸识别系统

    人脸识别技术已成为现代科技的重要基石,广泛应用于安全监控、门禁系统以及用户身份认证等领域。新唐科技基于 NuMaker-M55M1 平台的人脸识别系统,结合多种核心技术组件,包括图像处理技术
    的头像 发表于 01-20 10:31 156次阅读

    校园人脸识别闸机通道的应用

    决策的融合,为构建平安、智慧校园奠定了坚实基础。人脸识别闸机通道在校园大门处的部署,首先实现了对校园入口的智能化管控。通过高精度的人脸识别算法,系统能够迅速准确地识
    的头像 发表于 01-15 15:02 99次阅读
    校园<b class='flag-5'>人脸</b>识别闸机通道的应用

    ElfBoard开源项目|百度智能云平台的人脸识别项目

    百度智能云平台的人脸识别项目,旨在利用其强大的人脸识别服务实现自动人脸识别。选择百度智能云的原因是其高效的API接口和稳定的服务质量,能够帮助开发者快速实现人脸识别应用。 本项目使用
    的头像 发表于 12-24 10:54 603次阅读
    ElfBoard开源项目|百度智能云平台<b class='flag-5'>的人脸</b>识别项目

    如何选择合适的人脸门禁系统?人脸打卡门禁哪款好?

    在当今这个智能化、高效化的时代,办公场所的安全与管理效率成为了企业不可忽视的重要环节。随着人脸识别技术的日益成熟,人脸门禁系统因其独特的优势,逐渐成为众多办公写字楼出入口管理的首选方案。本文将探讨人脸
    的头像 发表于 12-17 15:19 223次阅读
    如何选择合适<b class='flag-5'>的人脸</b>门禁系统?<b class='flag-5'>人脸</b>打卡门禁哪款好?

    FacenetPytorch人脸识别方案--基于米尔全志T527开发板

    算法实现人脸识别深度神经网络1.简介 Facenet-PyTorch 是一个基于 PyTorch 框架实现的人脸识别库。它提供了 FaceNet 模型的 PyTorch 实现,可以用于训练自己
    发表于 11-28 15:57

    【「从算法到电路—数字芯片算法的电路实现」阅读体验】+内容简介

    内容简介这是一本深入解读基础算法及其电路设计,以打通算法研发到数字IC设计的实现屏障,以及指导芯片设计工程师从底层掌握复杂电路设计与优化方法为目标的专业技术书。任何芯片(如WiFi芯片、5G芯片
    发表于 11-21 17:14

    《DNK210使用指南 -CanMV版 V1.0》第四十五章 人脸识别实验

    与先前录入的人脸特征进行对比,如果得分高于阈值,则能成功识别人脸,最后将识别结果同原始图像在LCD上进行显示。2. 按下KEY0按键可以录入当前人脸的特征。45.2.2 硬件资源本章实
    发表于 11-18 14:30

    如何用OpenCV的相机捕捉视频进行人脸检测--基于米尔NXP i.MX93开发板

    : breakvideo.release()cv2.destroyAllWindows() 保存后执行”python3 opencv_test.py OpenCV装好后,可以为后面的人脸检测提供可行性。 要实现人脸识别
    发表于 11-15 17:58

    隧道人脸识别门禁系统应用于隧道工程等场所的智能化安全管理系统

    一、系统组成   1、人脸识别设备 高清摄像头:能够清晰捕捉人员的面部图像,即使在光线较暗的隧道环境中也能有效识别。 识别算法:采用先进的人脸识别算法,快速准确地识别人员身份,误识率低
    的头像 发表于 09-04 16:38 494次阅读
    隧道<b class='flag-5'>人脸</b>识别门禁系统应用于隧道工程等场所的智能化安全管理系统

    基于FPGA的人脸识别技术

    基于FPGA(现场可编程逻辑门阵列)的人脸识别技术,是一种结合了高效并行处理能力和灵活可编程性的先进图像处理解决方案。这种技术在安全监控、身份认证、人机交互等领域具有广泛应用前景。以下将详细介绍基于FPGA的人脸识别技术,包括其基本原理、系统构成、
    的头像 发表于 07-17 11:42 1577次阅读

    基于OpenCV的人脸识别系统设计

    基于OpenCV的人脸识别系统是一个复杂但功能强大的系统,广泛应用于安全监控、人机交互、智能家居等多个领域。下面将详细介绍基于OpenCV的人脸识别系统的基本原理、实现步骤,并附上具体的代码示例。
    的头像 发表于 07-11 15:37 1.5w次阅读

    人脸识别模型训练是什么意思

    人脸识别模型训练是指通过大量的人脸数据,使用机器学习或深度学习算法,训练出一个能够识别和分类人脸的模型。这个模型可以应用于各种场景,如安防监控、身份认证、社交媒体等。下面将介绍
    的头像 发表于 07-04 09:16 736次阅读

    人脸检测模型有哪些

    : Viola-Jones 算法 Viola-Jones 算法是一种基于 Haar 特征和 AdaBoost 算法的人脸检测方法。它通过训练一个级联分类器来实现
    的头像 发表于 07-03 17:05 1148次阅读

    如何挑选理想的人脸识别考勤系统产品?人脸识别设备的选型

    如何挑选理想的人脸识别考勤系统产品?在挑选理想的人脸识别考勤系统产品时,需要综合考虑多个方面,包括但不限于设备的性能、兼容性、数据存储能力、环境适应性以及售后服务等因素。以下是根据提供的搜索结果
    的头像 发表于 06-05 14:59 541次阅读
    如何挑选理想<b class='flag-5'>的人脸</b>识别考勤系统产品?<b class='flag-5'>人脸</b>识别设备的选型

    人脸识别技术的原理是什么 人脸识别技术的特点有哪些

    人脸识别技术的原理 人脸识别技术是一种通过计算机以图像或视频为输入,识别、检测、跟踪和分析人脸的技术。其原理基于计算机视觉和模式识别等领域的理论和算法。下面将详细介绍
    的头像 发表于 02-18 13:52 2361次阅读