虹软人脸识别API

版本:3.0.3902010101.5

参考:ARCSOFT_ARC_FACE_DEVELOPER'S_GUIDE.pdf

更为详尽的示例。

使用同一个引擎句柄不支持多线程调用同一个算法接口,需对同一个接口进行多线程调用需要启动多个引擎。

ASFGetVersion

获取SDK版本信息。无需激活或初始化即可调用。

const ASF_VERSION ASFGetVersion();
示例:
#include <iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    ASF_VERSION version = ASFGetVersion();
    cout << version.Version << endl;
    cout << version.BuildDate << endl;
    cout << version.CopyRight << endl;
    return 0;
}

ASFGetActiveFileInfo

获取激活文件信息接口

MRESULT ASFGetActiveFileInfo(
    LPASF_ActiveFileInfo  activeFileInfo  // [out] 激活文件信息
);
示例:
#include <iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    ASF_ActiveFileInfo info;
    MRESULT res = ASFGetActiveFileInfo(&info);
    if (res != MOK) {
        cout << "ASFGetActiveFileInfo fail: " << res << endl;
    }
    else {
        cout << "ASFGetActiveFileInfo success: " << info.appId << endl;
    }
    return 0;
}

ASFOnlineActivation

用于在线激活SDK。

初次使用SDK需要联网激活,激活成功后无需重复调用,可离线使用。

MRESULT ASFOnlineActivation(
    MPChar                AppId,            // [in]  APPID    官网下载
    MPChar                SDKKey            // [in]  SDKKEY    官网下载
);
示例
#include <iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

#define APPID "your_appid"
#define SDKKEY "your_sdkkey"

int main() {
    MRESULT res = ASFOnlineActivation(APPID, SDKKEY);
    if (res != MOK && res != MERR_ASF_ALREADY_ACTIVATED) {
        cout << "ASFOnlineActivation fail: " << res << endl;
    }
    else {
        cout << "ASFOnlineActivation success: " << res << endl;
    }
    return 0;
}

注意: 实际使用需要更改ASFOnlineActivation数据结构:

MRESULT ASFOnlineActivation(
    MPCChar                AppId,            // [in]  APPID    官网下载
    MPCChar                SDKKey            // [in]  SDKKEY    官网下载
);

ASFActivation

用于在线激活SDK。

ASFOnlineActivation功能一致。

MRESULT ASFActivation(
    MPChar                AppId,            // [in]  APPID    官网下载
    MPChar                SDKKey            // [in]  SDKKEY    官网下载
);
示例:
#include <iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

#define APPID "your_appid"
#define SDKKEY "your_sdkkey"

int main() {
    MRESULT res = ASFActivation(APPID, SDKKEY);
    if (res != MOK && res != MERR_ASF_ALREADY_ACTIVATED) {
        cout << "ASFActivation fail: " << res << endl;
    }
    else {
        cout << "ASFActivation success: " << res << endl;
    }
    return 0;
}

注意: 实际使用需要更改ASFActivation数据结构:

MRESULT ASFActivation(
    MPCChar                AppId,            // [in]  APPID    官网下载
    MPCChar                SDKKey            // [in]  SDKKEY    官网下载
);

ASFInitEngine

初始化引擎。

MRESULT ASFInitEngine(
    ASF_DetectMode        detectMode,                    // [in]    
    //         AF_DETECT_MODE_VIDEO 视频模式:适用于摄像头预览,视频文件识别
    //        AF_DETECT_MODE_IMAGE 图片模式:适用于静态图片的识别
    ASF_OrientPriority    detectFaceOrientPriority,    // [in]    检测脸部的角度优先值,参考 ArcFaceCompare_OrientPriority
    MInt32                detectFaceScaleVal,            // [in] 用于数值化表示的最小人脸尺寸,该尺寸代表人脸尺寸相对于图片长边的占比
    // video 模式有效值范围[2, 32], 推荐值为 16
    // image 模式有效值范围[2, 32], 推荐值为 32
    MInt32                detectFaceMaxNum,            // [in] 最大需要检测的人脸个数,取值范围[1, 50]
    MInt32                combinedMask,                // [in] 用户选择需要检测的功能组合,可单个或多个
    MHandle*            hEngine                        // [out] 初始化返回的引擎handle
);

VIDEO模式

  • 对视频流中的人脸进行追踪,人脸框平滑过渡,不会出现跳框现象。
  • 使用摄像头需要做预览显示,每一帧都需要做人脸检测,人脸检测耗时短不会出现卡顿的现象。
  • 视频模式下人脸追踪和带有一个FaceId值,标记一张人脸从进入画面直到离开画面。FaceId值不变,可用于业务中优化程序性能。

IMAGE模式

  • 针对单张图片进行人脸检测,精度更高。
  • 注册人脸库时,建议使用精度更高的IMAGE模式。

模式选择

  1. 摄像头中获取数据并需要预览显示,推荐选择VIDEO模式;
  2. 处理静态图像数据,类似注册人脸库时,推荐使用IMAGE模式;
  3. 同时进行IMAGE模式人脸检测和VIDEO模式人脸检测,需要创建一个VIDEO模式的引擎和一个IMAGE模式的引擎。

detectFaceOrientPriority

detect_face_orient_priority

detectFaceScaleVal

识别的最小人脸比例 = 图片长边 / 人脸框长边比值

默认推荐值:VIDEO模式推荐16;IMAGE模式推荐32.

//如下图所示
//图片尺寸 400 x 600
//人脸尺寸 300 x 300

minScale = 600 / 300    //若为小数,向上取整(例如:2.53 取值为 3)

detect_face_scale

设置推荐:

根据使用场景适当调整。门禁场景推荐使用VIDEO模式,detectFaceScaleVal设置为16.

用户使用场景下的成像质量比较高,设置为32,可以在相对较远的位置检测到人脸并比对通过,效果更佳,达到无感通行。

combinedMask

针对算法功能会有常量值与之一一对应,根据业务需求进行自由选择,不需要的属性可以不用初始化,减少内存占用。

#define ASF_FACE_DETECT     0x00000001     //人脸检测
#define ASF_FACERECOGNITION    0x00000004    //人脸特征
#define ASF_AGE             0x00000008    //年龄
#define ASF_GENDER            0x00000010    //性别
#define ASF_FACE3DANGLE     0x00000020    //3D角度
#define ASF_LIVENESS         0x00000080    //RGB活体
#define ASF_IR_LIVENESS     0x00000400    //IR活体

说明:

  1. 人脸识别一般需要ASF_FACE_DETECTASF_FACERECOGNITION属性。
  2. 需要防止纸张、屏幕等攻击可以传入ASF_LIVENESSASF_IR_LIVENESSRGBIR活体检测根据用户的摄像头类型以及实际的业务需求来决定如何选择。
  3. ASF_AGE/ASF_GENDER/ASF_FACE3DANGLE根据业务需求进行选择即可。

这些属性均是以常量值进行定义,可通过|位运算符进行组合使用。

例如:MInt32 combinedMask = ASF_FACE_DETECT | ASF_FACERECOGNITION |ASF_LIVENESS

示例:
#include <iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

#define APPID "your_appid"
#define SDKKEY "your_sdkkey"

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 32;
    MInt32 face_num = 1;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS;

    MRESULT res = ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
        );

    if (res != MOK) {
        cout << "ASFInitEngine fail: " << res << endl;
    }
    else {
        cout << "ASFInitEngine success: " << res << endl;
    }
    return 0;
}

ASFUninitEngine

销毁SDK引擎。

MRESULT ASFUninitEngine(
    MHandle hEngine
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 1;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS
        | ASF_IR_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    MRESULT res = ASFUninitEngine(handle);
    if (res != MOK) {
        cout << "ASFUninitEngine fail: " << res << endl;
    }
    else {
        cout << "ASFUninitEngine success: " << res << endl;
    }

    return 0;
}

ASFDetectFaces

VIDEO模式下调用人脸追踪功能。

IMAGE模式下调用人脸检测功能。

初始化中detectFaceOrientPrioritydetectFaceScaleValdetectFaceMaxNum参数的设置,对能否检测到人脸以及检测到几张人脸都有决定性作用。

图像宽度需要四字节对齐(宽度为4的倍数),否则需要裁剪。

MRESULT ASFDetectFaces(
    MHandle                hEngine,                            // [in] 引擎handle
    MInt32                width,                                // [in] 图片宽度
    MInt32                height,                                // [in] 图片高度
    MInt32                format,                                // [in] 颜色空间格式
    MUInt8*                imgData,                            // [in] 图片数据
    LPASF_MultiFaceInfo    detectedFaces,                        // [out]检测到的人脸信息 
    ASF_DetectModel        detectModel = ASF_DETECT_MODEL_RGB    // [in] 预留字段,当前版本使用默认参数即可
);

detect_faces

示例:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv/cv.h>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 50;
    MInt32 mask = ASF_FACE_DETECT;

    MRESULT res_init = ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    if (res_init != MOK) {
        cout << "ASFInitEngine fail: " << res_init << endl;
    }
    else {
        cout << "ASFInitEngine success: " << res_init << endl;
    }

    cv::Mat img = cv::imread("C:\\Users\\milk\\Desktop\\many.jpg");
    // 四字节对齐,原始图像裁剪
    cv::Rect area(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4);
    cv::Mat img_cut = img(area);
    ASF_MultiFaceInfo mult_face_info;
    MRESULT res_detect = ASFDetectFaces(
        handle,
        img_cut.cols,
        img_cut.rows,
        ASVL_PAF_RGB24_B8G8R8,
        img_cut.data,
        &mult_face_info
    );
    if (res_detect != MOK) {
        cout << "ASFDetectFaces fail: " << res_detect << endl;
    }
    else {
        cout << "ASFDetectFaces success: " << res_detect << endl;

        cv::putText(img, "face num: " + to_string(mult_face_info.faceNum), cv::Point(30, 30), cv::FONT_ITALIC, 1, cv::Scalar(0, 0, 255), 2);
        for (int i = 0; i < mult_face_info.faceNum; ++i) {
            cv::rectangle(
                img,
                cv::Point(mult_face_info.faceRect[i].left, mult_face_info.faceRect[i].top),
                cv::Point(mult_face_info.faceRect[i].right, mult_face_info.faceRect[i].bottom), 
                cv::Scalar(0, 0, 255), 
                2);
        }
    }

    cv::imshow("img", img);
    cv::waitKey(0);
    return 0;
}

ASFDetectFacesEx

ASFDetectFaces功能一致,但采用结构体的形式传入图像数据,对更高精度的图像兼容性更好。

MRESULT ASFDetectFacesEx(
    MHandle                hEngine,                            // [in] 引擎handle
    LPASF_ImageData        imgData,                            // [in] 图片数据
    LPASF_MultiFaceInfo    detectedFaces,                        // [out] 检测到的人脸信息
    ASF_DetectModel        detectModel = ASF_DETECT_MODEL_RGB    // [in]    预留字段,当前版本使用默认参数即可
);
示例:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv/cv.h>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 50;
    MInt32 mask = ASF_FACE_DETECT;

    MRESULT res_init = ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    if (res_init != MOK) {
        cout << "ASFInitEngine fail: " << res_init << endl;
    }
    else {
        cout << "ASFInitEngine success: " << res_init << endl;
    }

    cv::Mat img = cv::imread("C:\\Users\\milk\\Desktop\\many.jpg");
    // 四字节对齐,原始图像裁剪
    cv::Rect area(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4);
    cv::Mat img_cut = img(area);

    // 使用结构体形式传入,对更高精度的图像兼容性更好
    ASVLOFFSCREEN asvl_img;
    asvl_img.i32Width = img_cut.cols;
    asvl_img.i32Height = img_cut.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;

    ASF_MultiFaceInfo mult_face_info;
    MRESULT res_detect = ASFDetectFacesEx(handle, &asvl_img, &mult_face_info);

    if (res_detect != MOK) {
        cout << "ASFDetectFaces fail: " << res_detect << endl;
    }
    else {
        cout << "ASFDetectFaces success: " << res_detect << endl;

        cv::putText(img, "face num: " + to_string(mult_face_info.faceNum), cv::Point(30, 30), cv::FONT_ITALIC, 1, cv::Scalar(0, 0, 255), 2);
        for (int i = 0; i < mult_face_info.faceNum; ++i) {
            cv::rectangle(
                img, 
                cv::Point(mult_face_info.faceRect[i].left, mult_face_info.faceRect[i].top),
                cv::Point(mult_face_info.faceRect[i].right,mult_face_info.faceRect[i].bottom), 
                cv::Scalar(0, 0, 255), 
                2);
        }
    }

    cv::imshow("img", img);
    cv::waitKey(0);


    return 0;
}

ASFFaceFeatureExtract

单人脸特征提取。

在进行第二次特征提取时,覆盖第一次特征提取结果。

例如:1:1的比对分别对两张图片进行特征提取,若使用同一个引擎,第一次特征提取需要拷贝保存,再进行第二次特征提取,否则在比对时输出的结果为1。

MRESULT ASFFaceFeatureExtract(
    MHandle                    hEngine,        // [in]    引擎handle
    MInt32                    width,            // [in] 图片宽度
    MInt32                    height,            // [in] 图片高度
    MInt32                    format,            // [in] 颜色空间格式
    MUInt8*                    imgData,        // [in] 图片数据
    LPASF_SingleFaceInfo    faceInfo,        // [in] 单张人脸位置和角度信息
    LPASF_FaceFeature        feature            // [out] 人脸特征
);
示例:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv/cv.h>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 50;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION;

    MRESULT res_init = ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    if (res_init != MOK) {
        cout << "ASFInitEngine fail: " << res_init << endl;
    }
    else {
        cout << "ASFInitEngine success: " << res_init << endl;
    }

    cv::Mat img = cv::imread("C:\\Users\\milk\\Desktop\\many.jpg");
    // 四字节对齐,原始图像裁剪
    cv::Rect area(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4);
    cv::Mat img_cut = img(area);

    // 使用结构体形式传入,对更高精度的图像兼容性更好
    ASVLOFFSCREEN asvl_img;
    asvl_img.i32Width = img_cut.cols;
    asvl_img.i32Height = img_cut.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;

    ASF_MultiFaceInfo mult_face_info;

    MRESULT res_detect = ASFDetectFacesEx(handle, &asvl_img, &mult_face_info);

    if (res_detect != MOK) {
        cout << "ASFDetectFaces fail: " << res_detect << endl;
    }
    else {
        cout << "ASFDetectFaces success: " << res_detect << endl;

        cv::putText(img, "face num: " + to_string(mult_face_info.faceNum), cv::Point(30, 30), cv::FONT_ITALIC, 1, cv::Scalar(0, 0, 255), 2);
        for (int i = 0; i < mult_face_info.faceNum; ++i) {
            cv::rectangle(
                img, 
                cv::Point(mult_face_info.faceRect[i].left, mult_face_info.faceRect[i].top),
                cv::Point(mult_face_info.faceRect[i].right, mult_face_info.faceRect[i].bottom), 
                cv::Scalar(0, 0, 255), 
                2);
            ASF_FaceFeature feature;
            ASF_SingleFaceInfo single_face_info;
            single_face_info.faceRect = mult_face_info.faceRect[i];
            single_face_info.faceOrient = mult_face_info.faceOrient[i];
            MRESULT res_extract = ASFFaceFeatureExtract(handle, img.cols, img.rows, ASVL_PAF_RGB24_B8G8R8, img.data, &single_face_info, &feature);
            cout << "Face: " << i << " --- ";
            if (res_extract != MOK) {
                cout << "ASFFaceFeatureExtract faile: " << res_extract << endl;
            }
            else {
                cout << "ASFFaceFeatureExtract success: " << res_extract << endl;
            }
        }
    }

    cv::imshow("img", img);
    cv::waitKey(0);


    return 0;
}

ASFFaceFeatureExtractEx

单人脸特征提取。

ASFFaceFeatureExtract功能一致,但采用结构体的形式传入图像数据,对更高精度的图像兼容性更好。

在进行第二次特征提取时,会覆盖第一次特征提取的结果。

  • 1:1的比对分别对两张图片进行特征提取,若使用同一个引擎,第一次特征提取需要拷贝保存,再进行第二次特征提取,否则在比对时输出的结果为1。
  • 1:N搜索可以预先提取N张人脸特征存放在数据库或缓存中,进行比对识别。
MRESULT ASFFaceFeatureExtractEx(
    MHandle                    hEngine,        // [in]    引擎handle
    LPASF_ImageData            imgData,        // [in] 图像数据
    LPASF_SingleFaceInfo    faceInfo,        // [in] 单张人脸位置和角度信息
    LPASF_FaceFeature        feature            // [out] 人脸特征
);
示例:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv/cv.h>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 50;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION;

    MRESULT res_init = ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    if (res_init != MOK) {
        cout << "ASFInitEngine fail: " << res_init << endl;
    }
    else {
        cout << "ASFInitEngine success: " << res_init << endl;
    }

    cv::Mat img = cv::imread("C:\\Users\\milk\\Desktop\\many.jpg");
    // 四字节对齐,原始图像裁剪
    cv::Rect area(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4);
    cv::Mat img_cut = img(area);

    // 使用结构体形式传入,对更高精度的图像兼容性更好
    ASVLOFFSCREEN asvl_img;
    asvl_img.i32Width = img_cut.cols;
    asvl_img.i32Height = img_cut.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;

    ASF_MultiFaceInfo mult_face_info;

    MRESULT res_detect = ASFDetectFacesEx(handle, &asvl_img, &mult_face_info);

    if (res_detect != MOK) {
        cout << "ASFDetectFaces fail: " << res_detect << endl;
    }
    else {
        cout << "ASFDetectFaces success: " << res_detect << endl;

        cv::putText(img, "face num: " + to_string(mult_face_info.faceNum), cv::Point(30, 30), cv::FONT_ITALIC, 1, cv::Scalar(0, 0, 255), 2);
        for (int i = 0; i < mult_face_info.faceNum; ++i) {
            cv::rectangle(
                img, 
                cv::Point(mult_face_info.faceRect[i].left, mult_face_info.faceRect[i].top),
                cv::Point(mult_face_info.faceRect[i].right, mult_face_info.faceRect[i].bottom), 
                cv::Scalar(0, 0, 255), 
                2);
            ASF_FaceFeature feature;
            ASF_SingleFaceInfo single_face_info;
            single_face_info.faceRect = mult_face_info.faceRect[i];
            single_face_info.faceOrient = mult_face_info.faceOrient[i];

            ASVLOFFSCREEN asvl_img;
            asvl_img.i32Width = img_cut.cols;
            asvl_img.i32Height = img_cut.rows;
            asvl_img.pi32Pitch[0] = img.step;
            asvl_img.ppu8Plane[0] = img.data;
            asvl_img.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;

            MRESULT res_extract = ASFFaceFeatureExtractEx(handle, &asvl_img, &single_face_info, &feature);
            cout << "Face: " << i << " --- ";
            if (res_extract != MOK) {
                cout << "ASFFaceFeatureExtract faile: " << res_extract << endl;
            }
            else {
                cout << "ASFFaceFeatureExtract success: " << res_extract << endl;
            }
        }
    }

    cv::imshow("img", img);
    cv::waitKey(0);


    return 0;
}

ASFFaceFeatureCompare

人脸特征比对,输出比对相似度。

MRESULT ASFFaceFeatureCompare(
    MHandle                    hEngine,                        // [in] 引擎handle
    LPASF_FaceFeature        feature1,                        // [in] 待比较人脸特征1
    LPASF_FaceFeature        feature2,                        // [in] 待比较人脸特征2
    MFloat*                    confidenceLevel,                // [out] 比较结果,置信度数值
    ASF_CompareModel        compareModel = ASF_LIFE_PHOTO    // [in] 
    //         ASF_LIFE_PHOTO:用于生活照之间的特征比对,推荐阈值0.80
    //        ASF_ID_PHOTO:用于证件照或证件照和生活照之间的特征比对,推荐阈值0.82
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

#define SafeFree(p) { if ((p)) free(p); (p) = nullptr; }
using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 2;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    ASF_FaceFeature copyfeature_base = { 0 }, copyfeature_todo = { 0 };

    {
        cv::Mat img_base = cv::imread("C:\\users\\milk\\desktop\\1.jpg");
        img_base = img_base(cv::Rect(0, 0, img_base.cols - img_base.cols % 4, img_base.rows - img_base.rows % 4));
        ASF_MultiFaceInfo multi_base;
        ASF_SingleFaceInfo faceinfo_base = { 0 };
        ASF_FaceFeature feature_base;
        ASFDetectFaces(handle, img_base.cols, img_base.rows, ASVL_PAF_RGB24_B8G8R8, img_base.data, &multi_base);
        cout << "num: " << multi_base.faceNum << endl;
        faceinfo_base.faceRect = multi_base.faceRect[0];
        faceinfo_base.faceOrient = multi_base.faceOrient[0];
        ASFFaceFeatureExtract(handle, img_base.cols, img_base.rows, ASVL_PAF_RGB24_B8G8R8, img_base.data, &faceinfo_base, &feature_base);

        copyfeature_base.featureSize = feature_base.featureSize;
        copyfeature_base.feature = (MByte*)malloc(feature_base.featureSize);
        memset(copyfeature_base.feature, 0, feature_base.featureSize);
        memcpy(copyfeature_base.feature, feature_base.feature, feature_base.featureSize);
    }

    {
        cv::Mat img_todo = cv::imread("C:\\users\\milk\\desktop\\6.jpg");
        img_todo = img_todo(cv::Rect(0, 0, img_todo.cols - img_todo.cols % 4, img_todo.rows - img_todo.rows % 4));
        ASF_MultiFaceInfo multi_todo;
        ASF_SingleFaceInfo faceinfo_todo = { 0 };
        ASF_FaceFeature feature_todo;
        ASFDetectFaces(handle, img_todo.cols, img_todo.rows, ASVL_PAF_RGB24_B8G8R8, img_todo.data, &multi_todo);
        cout << "num: " << multi_todo.faceNum << endl;
        faceinfo_todo.faceRect = multi_todo.faceRect[0];
        faceinfo_todo.faceOrient = multi_todo.faceOrient[0];
        ASFFaceFeatureExtract(handle, img_todo.cols, img_todo.rows, ASVL_PAF_RGB24_B8G8R8, img_todo.data, &faceinfo_todo, &feature_todo);


        copyfeature_todo.featureSize = feature_todo.featureSize;
        copyfeature_todo.feature = (MByte*)malloc(feature_todo.featureSize);
        memset(copyfeature_todo.feature, 0, feature_todo.featureSize);
        memcpy(copyfeature_todo.feature, feature_todo.feature, feature_todo.featureSize);
    }

    MFloat result;
    ASFFaceFeatureCompare(handle, &copyfeature_base, &copyfeature_todo, &result);
    cout << result << endl;
    SafeFree(copyfeature_base.feature);
    SafeFree(copyfeature_todo.feature);
    return 0;
}

ASFSetLivenessParam

设置RGB/IR活体阈值,若不设置内部默认RGB:0.5 IR:0.7

MRESULT ASFSetLivenessParam(
    MHandle                    hEngine,        // [in] 引擎handle
    LPASF_LivenessThreshold threshold        // [in] 活体置信度
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 2;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    ASF_LivenessThreshold threshold = { 0 };
    threshold.thresholdmodel_BGR = 0.5;
    threshold.thresholdmodel_IR = 0.7;
    MRESULT res = ASFSetLivenessParam(handle, &threshold);
    if (res != MOK) {
        cout << "ASFSetLivenessParam fail: " << res << endl;
    }
    else {
        cout << "ASFSetLivenessParam success: " << res << endl;
    }
    return 0;
}

ASFProcess

人脸属性检测(年龄、性别、人脸3D角度),最多支持4张人脸信息检测,超过部分返回未知(活体仅支持单张人脸检测,超出返回未知),接口不支持IR图像检测。

仅支持可见光图像检测。

MRESULT ASFProcess(
    MHandle                hEngine,            // [in] 引擎handle
    MInt32                width,                // [in] 图片宽度
    MInt32                height,                // [in] 图片高度
    MInt32                format,                // [in] 颜色空间格式
    MUInt8*                imgData,            // [in] 图片数据
    LPASF_MultiFaceInfo    detectedFaces,        // [in] 人脸信息,用户根据待检测的功能选择需要使用的人脸。
    MInt32                combinedMask        // [in] 只支持初始化时候指定需要检测的功能,在process时进一步在这个已经指定的功能集中继续筛选
    //      例如初始化的时候指定检测年龄和性别,在process的时候可以只检测年龄,但是不能检测除年龄和性别之外的功能    
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 2;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    cv::Mat img = cv::imread("C:\\users\\milk\\desktop\\fuck.jpg");
    img = img(cv::Rect(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4));

    ASF_MultiFaceInfo faces = { 0 };
    ASFDetectFaces(handle, img.cols, img.rows, ASVL_PAF_RGB24_B8G8R8, img.data, &faces);
    cout << "face num: " << faces.faceNum << endl;
    MInt32 process_mask = ASF_AGE | ASF_GENDER | ASF_FACE3DANGLE | ASF_LIVENESS;
    MRESULT result = ASFProcess(handle, img.cols, img.rows, ASVL_PAF_RGB24_B8G8R8, img.data, &faces, process_mask);
    if (result != MOK) {
        cout << "ASFProcess fail: " << result << endl;
    }
    else {
        cout << "ASFProcess success: " << result << endl;
    }
    return 0;
}

combinedMask

process接口中支持检测ASF_AGEASF_GENDERASF_FACE3DANGLEASF_LIVENESS四种属性,但是想检测这些属性,必须在初始化引擎接口中对想要检测的属性进行初始化。

关于初始化接口中combinedMaskASFProcess接口中combinedMask参数之间的关系:

  1. ASFProcess接口中combinedMask支持传入的属性有ASF_AGEASF_GENDERASF_FACE3DANGLEASF_LIVENESS
  2. 初始化中传入了ASF_FACE_DETECTASF_FACERECOGNITIONASF_AGEASF_LIVENESS属性。
  3. process可传入属性组合只有ASF_AGEASF_LIVENESSASF_AGE | ASF_LIVENESS

ASFProcessEx

ASFProcess功能一致,但采用结构体的形式传入图像数据,对更高精度的图像兼容任更好。

MRESULT ASFProcessEx(
    MHandle                hEngine,            // [in] 引擎handle
    LPASF_ImageData        imgData,            // [in] 图片数据
    LPASF_MultiFaceInfo detectedFaces,        // [in] 人脸信息,用户根据待检测的功能选择需要使用的人脸。
    MInt32                combinedMask        // [in] 只支持初始化时候指定需要检测的功能,在process时进一步在这个已经指定的功能集中继续筛选
    //      例如初始化的时候指定检测年龄和性别,在process的时候可以只检测年龄,但是不能检测除年龄和性别之外的功能 
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 2;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    cv::Mat img = cv::imread("C:\\users\\milk\\desktop\\fuck.jpg");
    img = img(cv::Rect(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4));
    ASVLOFFSCREEN asvl_img;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;
    asvl_img.i32Width = img.cols;
    asvl_img.i32Height = img.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;

    ASF_MultiFaceInfo faces = { 0 };
    ASFDetectFacesEx(handle, &asvl_img, &faces);
    cout << "face num: " << faces.faceNum << endl;

    MInt32 process_mask = ASF_AGE | ASF_GENDER | ASF_FACE3DANGLE | ASF_LIVENESS;

    MRESULT result = ASFProcessEx(handle, &asvl_img, &faces, process_mask);
    if (result != MOK) {
        cout << "ASFProcess fail: " << result << endl;
    }
    else {
        cout << "ASFProcess success: " << result << endl;
    }
    return 0;
}

ASFProcess_IR

仅支持单人脸IR活体检测(不支持年龄、性别、3D角度的检测),超出返回未知。

MRESULT ASFProcess_IR(
    MHandle                hEngine,            // [in] 引擎handle
    MInt32                width,                // [in] 图片宽度
    MInt32                height,                // [in] 图片高度
    MInt32                format,                // [in] 颜色空间格式
    MUInt8*                imgData,            // [in] 图片数据
    LPASF_MultiFaceInfo    detectedFaces,        // [in] 人脸信息,用户根据待检测的功能选择需要使用的人脸。
    MInt32                combinedMask        // [in] 目前只支持传入ASF_IR_LIVENESS属性的传入,且初始化接口需要传入 
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 1;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS
        | ASF_IR_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    cv::Mat img = cv::imread("C:\\users\\milk\\desktop\\unreal.jpg");
    cv::cvtColor(img, img, CV_BGR2GRAY);
    img = img(cv::Rect(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4));
    ASVLOFFSCREEN asvl_img;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_GRAY;
    asvl_img.i32Width = img.cols;
    asvl_img.i32Height = img.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;

    ASF_MultiFaceInfo faces = { 0 };
    ASFDetectFacesEx(handle, &asvl_img, &faces);
    cout << "face num: " << faces.faceNum << endl;

    MInt32 process_mask = ASF_IR_LIVENESS;

    MRESULT res = ASFProcess_IR(handle, img.cols, img.rows, ASVL_PAF_GRAY, img.data, &faces, process_mask);

    if (res != MOK) {
        cout << "ASFProcess_IR fail: " << res << endl;
    }
    else {
        cout << "ASFProcess_IR success: " << res << endl;
    }
    return 0;
}

ASFProcessEx_IR

ASFProcess_IR功能一致,但采用结构体的形式传入图像数据,对更高精度的图像兼容性更好。

MRESULT ASFProcessEx_IR(
    MHandle                hEngine,            // [in] 引擎handle
    LPASF_ImageData        imgData,            // [in] 图片数据
    LPASF_MultiFaceInfo detectedFaces,        // [in] 人脸信息,用户根据待检测的功能选择需要使用的人脸。
    MInt32                combinedMask        // [in] 目前只支持传入ASF_IR_LIVENESS属性的传入,且初始化接口需要传入
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 1;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS
        | ASF_IR_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    cv::Mat img = cv::imread("C:\\users\\milk\\desktop\\unreal.jpg");
    cv::cvtColor(img, img, CV_BGR2GRAY);
    img = img(cv::Rect(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4));

    ASVLOFFSCREEN asvl_img;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_GRAY;
    asvl_img.i32Width = img.cols;
    asvl_img.i32Height = img.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;

    ASF_MultiFaceInfo faces = { 0 };
    ASFDetectFacesEx(handle, &asvl_img, &faces);
    cout << "face num: " << faces.faceNum << endl;

    MInt32 process_mask = ASF_IR_LIVENESS;

    MRESULT res = ASFProcessEx_IR(handle, &asvl_img, &faces, process_mask);

    if (res != MOK) {
        cout << "ASFProcessEx_IR fail: " << res << endl;
    }
    else {
        cout << "ASFProcessEx_IR success: " << res << endl;
    }
    return 0;
}

ASFGetAge

获取年龄信息。

MRESULT ASFGetAge(
    MHandle hEngine,                // [in] 引擎handle
    LPASF_AgeInfo ageInfo            // [out] 检测到的年龄信息
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 1;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    cv::Mat img = cv::imread("C:\\users\\milk\\desktop\\ding.jpg");
    img = img(cv::Rect(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4));
    ASVLOFFSCREEN asvl_img;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;
    asvl_img.i32Width = img.cols;
    asvl_img.i32Height = img.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;

    ASF_MultiFaceInfo faces = { 0 };
    ASFDetectFacesEx(handle, &asvl_img, &faces);
    cout << "face num: " << faces.faceNum << endl;

    MInt32 process_mask = ASF_AGE | ASF_GENDER | ASF_FACE3DANGLE | ASF_LIVENESS;

    ASFProcessEx(handle, &asvl_img, &faces, process_mask);

    ASF_AgeInfo age = { 0 };
    MRESULT res = ASFGetAge(handle, &age);
    if (res != MOK) {
        cout << "ASFGetAge fail: " << res << endl;
    }
    else {
        cout << "age: " << age.ageArray[0] << endl;
    }
    return 0;
}

ASFGetGender

获取性别信息。

MRESULT ASFGetGender(
    MHandle hEngine,                // [in] 引擎handle
    LPASF_GenderInfo genderInfo        // [out] 检测到的性别信息
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 1;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    cv::Mat img = cv::imread("C:\\users\\milk\\desktop\\17\\522627199707165616.jpg");
    img = img(cv::Rect(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4));
    ASVLOFFSCREEN asvl_img;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;
    asvl_img.i32Width = img.cols;
    asvl_img.i32Height = img.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;

    ASF_MultiFaceInfo faces = { 0 };
    ASFDetectFacesEx(handle, &asvl_img, &faces);
    cout << "face num: " << faces.faceNum << endl;

    MInt32 process_mask = ASF_AGE | ASF_GENDER | ASF_FACE3DANGLE | ASF_LIVENESS;

    ASFProcessEx(handle, &asvl_img, &faces, process_mask);

    ASF_GenderInfo gender = { 0 };
    MRESULT res = ASFGetGender(handle, &gender);
    if (res != MOK) {
        cout << "ASFGetGender fail: " << res << endl;
    }
    else {
        cout << "gender: ";
        if (gender.genderArray[0] == 1) {
            cout << "female";
        }
        else if (gender.genderArray[0] == 0) {
            cout << "male";
        }
        else {
            cout << "unknow";
        }
        cout << endl;
    }
    return 0;
}

ASFGetFace3DAngle

获取3D角度信息。

MRESULT ASFGetFace3DAngle(
    MHandle hEngine,                    // [in] 引擎handle
    LPASF_Face3DAngle p3DAngleInfo        // [out] 检测到脸部3D 角度信息
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 1;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    cv::Mat img = cv::imread("C:\\users\\milk\\desktop\\17\\522627199707165616.jpg");
    img = img(cv::Rect(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4));
    ASVLOFFSCREEN asvl_img;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;
    asvl_img.i32Width = img.cols;
    asvl_img.i32Height = img.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;

    ASF_MultiFaceInfo faces = { 0 };
    ASFDetectFacesEx(handle, &asvl_img, &faces);
    cout << "face num: " << faces.faceNum << endl;

    MInt32 process_mask = ASF_AGE | ASF_GENDER | ASF_FACE3DANGLE | ASF_LIVENESS;

    ASFProcessEx(handle, &asvl_img, &faces, process_mask);

    ASF_Face3DAngle angle = { 0 };
    MRESULT res = ASFGetFace3DAngle(handle, &angle);
    if (res != MOK) {
        cout << "ASFGetFace3DAngle fail: " << res << endl;
    }
    else {
        cout << "roll: " << angle.roll[0] << "\n"
            << "yaw: " << angle.yaw[0] << "\n"
            << "pitch: " << angle.pitch[0]
            << endl;
    }
    return 0;
}

ASFGetLivenessScore

获取RGB活体信息。

MRESULT ASFGetLivenessScore(
    MHandle hEngine,                    // [in] 引擎handle
    LPASF_LivenessInfo livenessInfo        // [out] 检测RGB活体结果
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 1;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS
        | ASF_IR_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    cv::Mat img = cv::imread("C:\\users\\milk\\desktop\\unreal.jpg");
    img = img(cv::Rect(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4));
    ASVLOFFSCREEN asvl_img;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_RGB24_B8G8R8;
    asvl_img.i32Width = img.cols;
    asvl_img.i32Height = img.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;

    ASF_MultiFaceInfo faces = { 0 };
    ASFDetectFacesEx(handle, &asvl_img, &faces);
    cout << "face num: " << faces.faceNum << endl;

    MInt32 process_mask = ASF_LIVENESS;
    ASFProcessEx(handle, &asvl_img, &faces, process_mask);
    ASF_LivenessInfo liveness = { 0 };
    MRESULT res = ASFGetLivenessScore(handle, &liveness);

    if (res != MOK) {
        cout << "ASFGetLivenessScore fail: " << res << endl;
    }
    else {
        cout << "ASFGetLivenessScore success: " << res << endl;
        cout << "status: " << liveness.isLive[0] << endl;
    }
    return 0;
}

ASFGetLivenessScore_IR

获取IR活体结果

MRESULT ASFGetLivenessScore_IR(
    MHandle                hEngine,            // [in] 引擎handle
    LPASF_LivenessInfo     irLivenessInfo        // [out] 检测到IR活体结果
);
示例:
#include <opencv2/opencv.hpp>
#include<iostream>

#include "arcsoft_face_sdk.h"
#include "merror.h"

#pragma comment(lib, "libarcsoft_face_engine.lib")

using namespace std;

int main() {
    MHandle handle = nullptr;
    MInt32 scale = 16;
    MInt32 face_num = 1;
    MInt32 mask = ASF_FACE_DETECT
        | ASF_FACERECOGNITION
        | ASF_AGE
        | ASF_GENDER
        | ASF_FACE3DANGLE
        | ASF_LIVENESS
        | ASF_IR_LIVENESS;

    ASFInitEngine(
        ASF_DETECT_MODE_IMAGE,
        ASF_OP_0_ONLY,
        scale,
        face_num,
        mask,
        &handle
    );

    cv::Mat img = cv::imread("C:\\users\\milk\\desktop\\unreal.jpg");
    cv::cvtColor(img, img, CV_BGR2GRAY);
    img = img(cv::Rect(0, 0, img.cols - img.cols % 4, img.rows - img.rows % 4));
    ASVLOFFSCREEN asvl_img;
    asvl_img.u32PixelArrayFormat = ASVL_PAF_GRAY;
    asvl_img.i32Width = img.cols;
    asvl_img.i32Height = img.rows;
    asvl_img.pi32Pitch[0] = img.step;
    asvl_img.ppu8Plane[0] = img.data;

    ASF_MultiFaceInfo faces = { 0 };
    ASFDetectFacesEx(handle, &asvl_img, &faces);
    cout << "face num: " << faces.faceNum << endl;

    MInt32 process_mask = ASF_IR_LIVENESS;
    ASFProcessEx_IR(handle, &asvl_img, &faces, process_mask);

    ASF_LivenessInfo liveness = { 0 };
    MRESULT res = ASFGetLivenessScore_IR(handle, &liveness);

    if (res != MOK) {
        cout << "ASFGetLivenessScore fail: " << res << endl;
    }
    else {
        cout << "ASFGetLivenessScore success: " << res << endl;
        cout << "status: " << liveness.isLive[0] << endl;
    }
    return 0;
}

comment: