资讯专栏INFORMATION COLUMN

Qt 下的虹软人脸识别SDK使用介绍

graf / 2054人阅读

摘要:简介本文主要会对虹软人脸识别在平台下的使用过程做简要介绍,其中包含材料准备环境搭建代码实现三个主要步骤,帮助我们有过程上的参考。

简介

本文主要会对虹软人脸识别SDK在 Qt 平台下的使用过程做简要介绍,其中包含材料准备、环境搭建、代码实现三个主要步骤,帮助我们有过程上的参考。

开发环境 : win10 Qt5.11.2(Mingw 32位)


材料准备

人脸识别SDK(ArcSoft_ArcFace)下载

虹软对外有免费的AI开发平台,包括人脸识别SDK、活体检测SDK、人证核验SDK,这里我们使用的是人脸检测SDK,详细可以登陆虹软官网进行具体功能查阅。

登陆 http://ai.arcsoft.com.cn/prod... 进行注册后下载ArcSoft_ArcFace 2.0版本。

需要注意的是,下载SDK的版本要与qt编译器版本一致。这里选择下载 windous(x86)版本。

下载完成后,首先阅读 releasenotes.txt -> ARCSOFT_ARC_FACE_DEVELOPER"S_GUIDE.pdf。

openCV 下载

这里我们直接下载编译好的 OpenCV(x86 MinGW 版)https://github.com/huihut/Ope...。

下载完成后,首先阅读 README.md。

环境搭建

新建Qt工程

在 .pro 文件里面添加OpenCV相关库:

win32 {
INCLUDEPATH += D:OpenCV-MinGW-Build-OpenCV-3.3.1include
INCLUDEPATH += D:OpenCV-MinGW-Build-OpenCV-3.3.1includeopencv
INCLUDEPATH += D:OpenCV-MinGW-Build-OpenCV-3.3.1includeopencv2
LIBS += D:OpenCV-MinGW-Build-OpenCV-3.3.1inlibopencv_*.dll
}
1. 打开 Qt 工程,添加ArcSoft_ArcFace相关库:
2. 鼠标右键,添加库,外部库;
3. 平台选中 windows,链接选中 动态,其它不做勾选;
4. 库文件指下载好的 ArcSoft_ArcFace 的lib、dll 文件;
5. 包含路径指下载好的 ArcSoft_ArcFace 库相关的头文件。

6. 鼠标右键,添加现有文件,把 ArcSoft_ArcFace 库相关的头文件添加到工程中。
HEADERS += 
ArcSoft_ArcFace/inc/amcomdef.h 
ArcSoft_ArcFace/inc/arcsoft_face_sdk.h 
ArcSoft_ArcFace/inc/asvloffscreen.h 
ArcSoft_ArcFace/inc/merror.h

复制运行相关 dll 文件

将ArcSoft_ArcFace 与 OpenCV 相关的 dll 文件复制到工程生成的应用程序文件夹。如果没有添加完整,生成的应用程序运行时,将提示“由于找不到 xxx_.dll,无法继续执行代码。重新安装程序可能会解决此问题”或者“应用程序无法正常启动0xc000007b”等问题。

代码实现

UI界面实现: 使用 Axure 画界面原型图,组件采用绝对定位方式。

void Wigdet::initUI()
{
    m_photoBox.setParent(this);
    m_photoBox.move(8, 7);
    m_photoBox.resize(422, 278);

    m_idCardBox.setParent(this);
    m_idCardBox.move(440, 7);
    m_idCardBox.resize(276, 154);
    
    m_valLab.setParent(this);
    m_valLab.move(482, 171);
    m_valLab.resize(33, 16);
    m_valLab.setText("阈 值:");
    
    m_valSpinBox.setParent(this);
    m_valSpinBox.move(544, 166);
    m_valSpinBox.resize(159, 24);
    m_valSpinBox.setSingleStep(0.01);
    m_valSpinBox.setMinimum(0.01);
    m_valSpinBox.setMaximum(1.00);
    m_valSpinBox.setValue(0.82);
    
    m_loadPhotoBtn.setParent(this);
    m_loadPhotoBtn.move(454, 197);
    m_loadPhotoBtn.resize(249, 24);
    m_loadPhotoBtn.setText("图像导入");

    m_loadIdCardBtn.setParent(this);
    m_loadIdCardBtn.move(454, 228);
    m_loadIdCardBtn.resize(249, 24);
    m_loadIdCardBtn.setText("ID卡导入");
    
    m_compareBtn.setParent(this);
    m_compareBtn.move(454, 257);
    m_compareBtn.resize(249, 24);
    m_compareBtn.setText("面部识别");
    
    setWindowIcon(QIcon(":/pic/pic/icon.png"));
    setWindowTitle("AI Changes life [ 1508539502@qq.com -- TianSong ]");

    setFixedSize(726, 295);
}

关键的槽函数

void Wigdet::initSLot()
{
    connect(&m_loadPhotoBtn, SIGNAL(clicked()), this, SLOT(onLoadPhotoBtnClicked()));
    connect(&m_loadIdCardBtn, SIGNAL(clicked()), this, SLOT(onLoadIdCardBtnClicked()));
    connect(&m_compareBtn, SIGNAL(clicked()), this, SLOT(onCompareBtnClicked()));
}

void Wigdet::onLoadPhotoBtnClicked();
void Wigdet::onLoadIdCardBtnClicked();
void Wigdet::onCompareBtnClicked();

重写 painEvent 事件函数

void Wigdet::paintEvent(QPaintEvent*);

人脸识别处理 (查阅帮助文档与示例代码)

#define APPID   "申请的APPID"   //APPID
#define SDKKey  "申请的SDKKey"  //SDKKey
#define MERR_ASF_BASE_ALREADY_ACTIVATED (0x16002) 

bool Wigdet::doCompare(Imag& img_photo, Imag& img_idcard, float val)
{
    bool pResult = false;

    /** 1. 激活SDK */
    MRESULT res = ASFActivation(const_cast(APPID), const_cast(SDKKey));
    if (MOK == res || MERR_ASF_BASE_ALREADY_ACTIVATED == res)
    {
        qDebug() << "ALActivation sucess: " << res;
    }
    else
    {
        qDebug() << "ALActivation fail: " << res;
    }

    /** 2. 初始化引擎 */
    MHandle handle = NULL;
    MInt32 mask = ASF_FACE_DETECT | ASF_FACERECOGNITION | ASF_AGE | ASF_GENDER | ASF_FACE3DANGLE;
    res = ASFInitEngine(static_cast(ASF_DETECT_MODE_IMAGE), ASF_OP_0_ONLY, 16, 5, mask, &handle);
    if (res == MOK)
    {
        qDebug() << "ALInitEngine sucess: " << res;
    }
    else
    {
        qDebug() << "ALInitEngine fail: " << res;
    }

    /** 3. 人脸检测 */
    img_photo.img.scaled(img_photo.img.width()/4*4, img_photo.img.height()/4*4).save("img1.png");
    img_idcard.img.scaled(img_idcard.img.width()/4*4, img_idcard.img.height()/4*4).save("img2.png");

    IplImage* img1  = cvLoadImage("img1.png");
    IplImage* img2  = cvLoadImage("img2.png");

    if (img1 && img2)
    {
        /** 3.1 第一张人脸特征提取 */
        ASF_MultiFaceInfo  detectedFaces1       = { 0 };
        ASF_SingleFaceInfo SingleDetectedFaces1 = { 0 };
        ASF_FaceFeature    feature1             = { 0 };
        ASF_FaceFeature    copyfeature1         = { 0 };
        res = ASFDetectFaces(handle, img1->width, img1->height, ASVL_PAF_RGB24_B8G8R8, (MUInt8*)img1->imageData, &detectedFaces1);
        if (MOK == res)
        {
            SingleDetectedFaces1.faceRect.left   = detectedFaces1.faceRect[0].left;
            SingleDetectedFaces1.faceRect.top    = detectedFaces1.faceRect[0].top;
            SingleDetectedFaces1.faceRect.right  = detectedFaces1.faceRect[0].right;
            SingleDetectedFaces1.faceRect.bottom = detectedFaces1.faceRect[0].bottom;
            SingleDetectedFaces1.faceOrient      = 0x05;

            qDebug() << detectedFaces1.faceNum;

            res = ASFFaceFeatureExtract(handle, img1->width, img1->height, ASVL_PAF_RGB24_B8G8R8, reinterpret_cast(img1->imageData), &SingleDetectedFaces1, &feature1);
            if (res == MOK)
            {
                /** 3.1.1 拷贝feature */
                copyfeature1.featureSize = feature1.featureSize;
                copyfeature1.feature = reinterpret_cast(malloc(static_cast(feature1.featureSize)));
                memset(copyfeature1.feature, 0, static_cast(feature1.featureSize));
                memcpy(copyfeature1.feature, feature1.feature, static_cast(feature1.featureSize));  

                int x = SingleDetectedFaces1.faceRect.left;
                int y = SingleDetectedFaces1.faceRect.top;
                int w = SingleDetectedFaces1.faceRect.right - SingleDetectedFaces1.faceRect.left;
                int h = SingleDetectedFaces1.faceRect.bottom - SingleDetectedFaces1.faceRect.top;

                img_photo.rect = QRect(x, y, w, h);

                /** 3.1.2 人脸信息检测 */
                MInt32 processMask = ASF_AGE | ASF_GENDER;
                res = ASFProcess(handle, img1->width, img1->height, ASVL_PAF_RGB24_B8G8R8, reinterpret_cast(img1->imageData), &detectedFaces1, processMask);
                if (res == MOK)
                {
                    qDebug() << "ASFProcess sucess: " << res;
                }
                else
                {
                    qDebug() << "ASFProcess fail: " << res;
                }

                /** 3.1.3 获取年龄 */
                ASF_AgeInfo ageInfo = { 0 };
                res = ASFGetAge(handle, &ageInfo);
                if (res == MOK)
                {
                    img_photo.age = ageInfo.ageArray[0];

                    qDebug() << ageInfo.ageArray[0];
                    qDebug() << "ASFGetAge sucess: " << res;
                }
                else
                {
                    qDebug() << "ASFGetAge fail: " << res;
                }

                /** 3.1.4 获取性别 */
                ASF_GenderInfo genderInfo = { 0 };
                res = ASFGetGender(handle, &genderInfo);
                if (res == MOK)
                {
                    img_photo.gender = genderInfo.genderArray[0];

                    qDebug() << genderInfo.genderArray[0];
                    qDebug() << "ASFGetGender sucess: " << res;
                }
                else
                {
                    qDebug() << "ASFGetGender fail: " << res;
                }

                qDebug() << "ASFFaceFeatureExtract 1 Success";
            }
            else
            {
                qDebug() << "ASFFaceFeatureExtract 1 fail: " << res;
            }
        }
        else
        {
            qDebug() << "ASFDetectFaces 1 fail: " << res;
        }

        /** 3.2 第二张人脸特征提取 */
    ASF_MultiFaceInfo    detectedFaces2       = { 0 };
        ASF_SingleFaceInfo  SingleDetectedFaces2 = { 0 };
        ASF_FaceFeature     feature2             = { 0 };
        res = ASFDetectFaces(handle, img2->width, img2->height, ASVL_PAF_RGB24_B8G8R8, reinterpret_cast(img2->imageData), &detectedFaces2);
        if (MOK == res)
        {
            SingleDetectedFaces2.faceRect.left   = detectedFaces2.faceRect[0].left;
            SingleDetectedFaces2.faceRect.top    = detectedFaces2.faceRect[0].top;
            SingleDetectedFaces2.faceRect.right  = detectedFaces2.faceRect[0].right;
            SingleDetectedFaces2.faceRect.bottom = detectedFaces2.faceRect[0].bottom;
            SingleDetectedFaces2.faceOrient      = detectedFaces2.faceOrient[0];

            res = ASFFaceFeatureExtract(handle, img2->width, img2->height, ASVL_PAF_RGB24_B8G8R8, reinterpret_cast(img2->imageData), &SingleDetectedFaces2, &feature2);
            if (res == MOK)
            {
                int x = SingleDetectedFaces2.faceRect.left;
                int y = SingleDetectedFaces2.faceRect.top;
                int w = SingleDetectedFaces2.faceRect.right - SingleDetectedFaces2.faceRect.left;
                int h = SingleDetectedFaces2.faceRect.bottom - SingleDetectedFaces2.faceRect.top;

                img_idcard.rect = QRect(x, y, w, h);

                qDebug() << "ASFFaceFeatureExtract 2 Success";
            }
            else
            {
                qDebug() << "ASFFaceFeatureExtract 2 fail: " << res;
            }
        }
        else
        {
            qDebug() << "ASFDetectFaces 2 fail: " << res;
        }

        /** 3.3 单人脸特征比对 */
        MFloat confidenceLevel;
        res = ASFFaceFeatureCompare(handle, ©feature1, &feature2, &confidenceLevel);
        if (res == MOK)
        {
            qDebug() << "ASFFaceFeatureCompare sucess: " << confidenceLevel;

            if( confidenceLevel >= val ) pResult = true;
        }
        else
        {
            qDebug() << "ASFFaceFeatureCompare fail: " << res;
        }
    }

    /** 4. 反初始化 */
    res = ASFUninitEngine(handle);
    if (res != MOK)
    {
        qDebug() << "ALUninitEngine fail: " << res;
    }
    else
    {
        qDebug() << "ALUninitEngine sucess: " << res;
    }

    return pResult;
}

以上步骤完成后,就可以正常的编译运行了。

【因篇幅的限制,部分函数实现没有展开,可以根据文章末尾链接到github 中下载查看】

注意事项

ArcSoft_ArcFace_S 版本需要与 Qt 编译器一致 x64 或者 x86
opencv 版本需要与 Qt 编译器一致 x64 或者 x86.

下载链接

OpenCV-MinGW-Build-OpenCV-3.3.1:
https://github.com/cocowts/Op...

ArcSoft_ArcFace_Windows_x86_V2.0:
https://github.com/cocowts/Ar...

Qt 工程:
https://github.com/cocowts/Qt...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/61357.html

相关文章

  • 虹软人脸识别 - ArcFace SDK介绍使用注意事项

    摘要:引擎的多线程使用单个引擎的同一功能模块中的算法功能函数不支持多线程调用,且调用过程中不能进行销毁。若需多线程调用,需要创建多个引擎。 很多朋友在开发人脸识别系统的时候,会遇到各种各样的问题,现在我们以安卓平台使用虹软的免费离线人脸识别SDK开发为例,给大家介绍一下如何开发一个带有图片的人脸检测、视频画面的人脸属性检测、人脸注册识别等功能的人脸识别系统。 一、获取SDK 1.进入ArcF...

    eternalshallow 评论0 收藏0
  • 虹软AI 人脸识别SDK接入 — 参数优化篇

    摘要:引言使用了免费的人脸识别算法,感觉还是很不错的,但是初次接触的话会对一些接口的参数有些疑问的。这里分享一下我对一些参数的验证结果这里以版本为例,基本一样,希望能更好的帮助各位接入虹软的人脸识别算法。 引言 使用了免费的人脸识别算法,感觉还是很不错的,但是初次接触的话会对一些接口的参数有些疑问的。这里分享一下我对一些参数的验证结果(这里以windows版本为例,linux、android...

    yibinnn 评论0 收藏0
  • 虹软AI 人脸识别SDK接入 — 参数优化篇

    摘要:引言使用了免费的人脸识别算法,感觉还是很不错的,但是初次接触的话会对一些接口的参数有些疑问的。这里分享一下我对一些参数的验证结果这里以版本为例,基本一样,希望能更好的帮助各位接入虹软的人脸识别算法。 引言 使用了免费的人脸识别算法,感觉还是很不错的,但是初次接触的话会对一些接口的参数有些疑问的。这里分享一下我对一些参数的验证结果(这里以windows版本为例,linux、android...

    Shisui 评论0 收藏0
  • 虹软人脸识别SDK - Java服务端的那些事

    摘要:最近有合作公司的项目需要服务端人脸识别的开发,于是就用了公司的人脸识别开发,由于之前对服务端开发介绍的资料比较少,正好这次又做了这个项目,花了几天的开发,这里就简单分享一下个人的见解。 最近有合作公司的项目需要服务端人脸识别的开发,于是就用了公司的人脸识别SDK开发,由于之前对服务端开发介绍的资料比较少,正好这次又做了这个项目,花了几天的开发,这里就简单分享一下个人的见解。 影响性能的...

    AlphaGooo 评论0 收藏0
  • 虹软人脸识别ArcFace2.0 Android SDK使用教程

    摘要:一获取进入的申请地址填写信息申请并提交申请通过后即可下载,查看和二功能介绍虹软包含人脸检测年龄信息检测性别信息检测人脸三维角度检测活体检测人脸特征提取人脸特征比对功能。在线程进行人脸检测时不可以在线程同时进行人脸检测。一、获取SDK 1.进入ArcFace2.0的申请地址 https://ai.arcsoft.com.cn/product/arcface.html 2.填写信息申请并提交 申...

    sutaking 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<