[code]csharpcode: using System; using System.Runtime.InteropServices; namespace Ycx_Tool.ArcFace { /// <summary> /// SDK接口 /// </summary> public class ASFFunctions { /// <summary> /// SDK动态链接库路径 /// </summary> public const string Dll_PATH = "libarcsoft_face_engine.dll"; ///<summary> ///设备信息获取 ///</summary> ///<param name="deviceInfo">设备信息</param> ///<returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFGetActiveDeviceInfo(ref IntPtr deviceInfo); /// <summary> /// 激活人脸识别SDK引擎函数 /// </summary> /// <param name="appId">SDK对应的APPID</param> /// <param name="sdkKey">SDK对应的SDKKEY</param> /// <param name="activeKey">SDK对应的ACTIVEKEY</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFOnlineActivation(string appId, string sdkKey,string activeKey); /// <summary> /// 离线激活 /// </summary> /// <param name="path"></param> /// <returns></returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFOfflineActivation(string path); /// <summary> /// 初始化引擎 /// </summary> /// <param name="detectMode">AF_DETECT_MODE_VIDEO 视频模式 | AF_DETECT_MODE_IMAGE 图片模式</param> /// <param name="detectFaceOrientPriority">检测脸部的角度优先值</param> /// <param name="detectFaceScaleVal">用于数值化表示的最小人脸尺寸</param> /// <param name="detectFaceMaxNum">最大需要检测的人脸个数</param> /// <param name="combinedMask">用户选择需要检测的功能组合,可单个或多个</param> /// <param name="pEngine">初始化返回的引擎handle</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFInitEngine(DetectionMode detectMode, ASF_OrientPriority detectFaceOrientPriority, int detectFaceScaleVal, int detectFaceMaxNum, int combinedMask, ref IntPtr pEngine); /// <summary> /// 人脸检测 /// </summary> /// <param name="pEngine">引擎handle</param> /// <param name="width">图像宽度</param> /// <param name="height">图像高度</param> /// <param name="format">图像颜色空间</param> /// <param name="imgData">图像数据</param> /// <param name="detectedFaces">人脸检测结果</param> /// <param name="detectModel">预留字段,当前版本使用默认参数即可</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFDetectFaces(IntPtr pEngine, int width, int height, int format, IntPtr imgData, IntPtr detectedFaces, ASF_DetectModel detectModel = ASF_DetectModel.ASF_DETECT_MODEL_RGB); /// <summary> /// 人脸信息检测(年龄/性别/人脸3D角度) /// </summary> /// <param name="pEngine">引擎handle</param> /// <param name="width">图像宽度</param> /// <param name="height">图像高度</param> /// <param name="format">图像颜色空间</param> /// <param name="imgData">图像数据</param> /// <param name="detectedFaces">人脸信息,用户根据待检测的功能裁减选择需要使用的人脸</param> /// <param name="combinedMask">只支持初始化时候指定需要检测的功能,在process时进一步在这个已经指定的功能集中继续筛选例如初始化的时候指定检测年龄和性别, 在process的时候可以只检测年龄, 但是不能检测除年龄和性别之外的功能</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFProcess(IntPtr pEngine, int width, int height, int format, IntPtr imgData, IntPtr detectedFaces, int combinedMask); /// <summary> /// 单人脸特征提取 /// </summary> /// <param name="pEngine">引擎handle</param> /// <param name="width">图像宽度</param> /// <param name="height">图像高度</param> /// <param name="format">图像颜色空间</param> /// <param name="imgData">图像数据</param> /// <param name="faceInfo">单张人脸位置和角度信息</param> /// <param name="faceFeature">人脸特征</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFFaceFeatureExtract(IntPtr pEngine, int width, int height, int format, IntPtr imgData, IntPtr faceInfo, IntPtr faceFeature,int threadNum = 1); /// <summary> /// 人脸特征比对 /// </summary> /// <param name="pEngine">引擎handle</param> /// <param name="faceFeature1">待比较人脸特征1</param> /// <param name="faceFeature2"> 待比较人脸特征2</param> /// <param name="similarity">相似度(0~1)</param> /// <param name="compareModel"></param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFFaceFeatureCompare(IntPtr pEngine, IntPtr faceFeature1, IntPtr faceFeature2, ref float similarity, ASF_CompareModel compareModel = ASF_CompareModel.ASF_LIFE_PHOTO); /// <summary> /// 获取年龄信息 /// </summary> /// <param name="pEngine">引擎handle</param> /// <param name="ageInfo">检测到的年龄信息</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFGetAge(IntPtr pEngine, IntPtr ageInfo); /// <summary> /// 获取性别信息 /// </summary> /// <param name="pEngine">引擎handle</param> /// <param name="genderInfo">检测到的性别信息</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFGetGender(IntPtr pEngine, IntPtr genderInfo); /// <summary> /// 获取3D角度信息 /// </summary> /// <param name="pEngine">引擎handle</param> /// <param name="p3DAngleInfo">检测到脸部3D角度信息</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFGetFace3DAngle(IntPtr pEngine, IntPtr p3DAngleInfo); /// <summary> /// 获取RGB活体结果 /// </summary> /// <param name="hEngine">引擎handle</param> /// <param name="livenessInfo">活体检测信息</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFGetLivenessScore(IntPtr hEngine, IntPtr livenessInfo); /// <summary> /// 该接口目前仅支持单人脸IR活体检测(不支持年龄、性别、3D角度的检测),默认取第一张人脸 /// </summary> /// <param name="pEngine">引擎handle</param> /// <param name="width">图片宽度</param> /// <param name="height">图片高度</param> /// <param name="format">颜色空间格式</param> /// <param name="imgData">图片数据</param> /// <param name="faceInfo">人脸信息,用户根据待检测的功能选择需要使用的人脸。</param> /// <param name="combinedMask">目前只支持传入ASF_IR_LIVENESS属性的传入,且初始化接口需要传入 </param> /// <returns></returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFProcess_IR(IntPtr pEngine, int width, int height, int format, IntPtr imgData, IntPtr faceInfo, int combinedMask); /// <summary> /// 获取IR活体结果 /// </summary> /// <param name="pEngine">引擎handle</param> /// <param name="irLivenessInfo">检测到IR活体结果</param> /// <returns></returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFGetLivenessScore_IR(IntPtr pEngine, IntPtr irLivenessInfo); /// <summary> /// 销毁引擎 /// </summary> /// <param name="pEngine">引擎handle</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFUninitEngine(IntPtr pEngine); /// <summary> /// 获取版本信息 /// </summary> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern ASF_VERSION ASFGetVersion(); /// <summary> /// 获取激活文件信息 /// </summary> /// <param name="activeFileInfo"> // [out] 激活文件信息</param> /// <returns></returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFGetActiveFileInfo(IntPtr activeFileInfo); /// <summary> /// 取值范围[0-1]内部默认数值RGB-0.5,IR-0.7, 用户可以根据实际需求,设置不同的阈值 /// </summary> /// <param name="hEngine">引擎handle</param> /// <param name="threshold">活体置信度</param> /// <returns></returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFSetLivenessParam(IntPtr hEngine, IntPtr threshold); /// <summary> /// VIDEO模式:人脸追踪 IMAGE模式:人脸检测 /// 图像数据以结构体形式传入,对采用更高字节对齐方式的图像兼容性更好 /// </summary> /// <param name="hEngine">引擎handle</param> /// <param name="imgData">图片数据</param> /// <param name="detectedFaces">检测到的人脸信息</param> /// <param name="detectModel">预留字段,当前版本使用默认参数即可</param> /// <returns></returns> [DllImport(Dll_PATH, EntryPoint = "ASFDetectFacesEx", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int ASFDetectFacesEx(IntPtr hEngine, IntPtr imgData, IntPtr detectedFaces, ASF_DetectModel detectModel = ASF_DetectModel.ASF_DETECT_MODEL_RGB); ///<summary> ///图像质量检测 ///</summary> /// <param name="hEngine">引擎handle</param> /// <param name="imgData">图片数据</param> /// <param name="detectedFaces">人脸位置信息</param> /// <param name="imageQualityInfo">图像质量检测结果</param> /// <param name="detectModel">预留字段,当前版本使用默认参数(ASF_DETECT_MODEL_RGB)即可</param> /// <returns>调用结果</returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFImageQualityDetectEx(IntPtr hEngine, IntPtr imgData, IntPtr detectedFaces, IntPtr imageQualityInfo, ASF_DetectModel detectModel = ASF_DetectModel.ASF_DETECT_MODEL_RGB); /// <summary> /// 年龄/性别/人脸3D角度(该接口仅支持RGB图像),最多支持4张人脸信息检测,超过部分返回未知 /// RGB活体仅支持单人脸检测,该接口不支持检测IR活体 /// </summary> /// <param name="hEngine">引擎handle</param> /// <param name="imgData">图片数据</param> /// <param name="detectedFaces">人脸信息,用户根据待检测的功能选择需要使用的人脸。</param> /// <param name="combinedMask">只支持初始化时候指定需要检测的功能,在process时进一步在这个已经指定的功能集中继续筛选</param> /// <returns></returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFProcessEx(IntPtr hEngine, IntPtr imgData, IntPtr detectedFaces, int combinedMask); /// <summary> /// 该接口目前仅支持单人脸IR活体检测(不支持年龄、性别、3D角度的检测),默认取第一张人脸 /// 图像数据以结构体形式传入,对采用更高字节对齐方式的图像兼容性更好 /// </summary> /// <param name="hEngine">引擎handle</param> /// <param name="imgData">图片数据</param> /// <param name="detectedFaces">人脸信息,用户根据待检测的功能选择需要使用的人脸。</param> /// <param name="combinedMask">目前只支持传入ASF_IR_LIVENESS属性的传入,且初始化接口需要传入</param> /// <returns></returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFProcessEx_IR(IntPtr hEngine, IntPtr imgData, IntPtr detectedFaces, int combinedMask); /// <summary> /// 单人脸特征提取 /// 图像数据以结构体形式传入,对采用更高字节对齐方式的图像兼容性更好 /// </summary> /// <param name="hEngine">引擎handle</param> /// <param name="imgData">图像数据</param> /// <param name="faceInfo">单张人脸位置和角度信息</param> /// <param name="feature">人脸特征</param> /// <returns></returns> [DllImport(Dll_PATH, CallingConvention = CallingConvention.Cdecl)] public static extern int ASFFaceFeatureExtractEx(IntPtr hEngine, IntPtr imgData, IntPtr faceInfo, IntPtr feature, int threadNum = 1); } } [code]csharpcode: using System; using System.Runtime.InteropServices; namespace Ycx_Tool.ArcFace { /// <summary> /// 公用方法 /// </summary> public class CommonUtil { /// <summary> /// 转化活体检测结果 /// </summary> /// <param name="liveness">活体检测值</param> /// <returns></returns> public static string TransLivenessResult(int liveness) { string rel = "不确定"; switch (liveness) { case 0: rel = "非真人"; break; case 1: rel = "真人"; break; case -2: rel = "传入人脸数>1"; break; case -3: rel = "人脸过小"; break; case -4: rel = "角度过大"; break; case -5: rel = "人脸超出边界"; break; case -1: default: rel = "不确定"; break; } return rel; } /// <summary> /// 将ImageInfo对象转化为ASF_ImageData结构体 /// </summary> /// <param name="imageInfo">ImageInfo对象</param> /// <returns>ASF_ImageData结构体</returns> public static ASF_ImageData TransImageDataStructByImageInfo(ImageInfo imageInfo) { ASF_ImageData asfImageData = new ASF_ImageData(); asfImageData.i32Width = imageInfo.width; asfImageData.i32Height = imageInfo.height; asfImageData.u32PixelArrayFormat = (uint)imageInfo.format; asfImageData.pi32Pitch = new int[4]; asfImageData.ppu8Plane = new IntPtr[4]; asfImageData.pi32Pitch[0] = imageInfo.widthStep; asfImageData.ppu8Plane[0] = imageInfo.imgData; return asfImageData; } } } [code]csharpcode: using System; using UnityEngine; using System.Drawing; using System.IO; namespace Ycx_Tool.ArcFace { public class SDKUtil { /// <summary> /// 图像处理引擎对象 /// </summary> private static FaceEngine imageEngine; /// <summary> /// 初始化SDK /// </summary> /// <param name="appid"></param> /// <param name="sdkkey"></param> /// <returns></returns> public static void Init_Sdk(string appid, string sdkkey,string activeKey) { imageEngine = new FaceEngine(); int retCode; try { retCode = ASFFunctions.ASFOnlineActivation(appid, sdkkey, activeKey); //int num= ASFFunctions.ASFOfflineActivation("86V11142Y13LKG21.dat"); //var num = ASFFunctions.ASFOnlineActivation(appid, sdkkey, "86V1-1142-Y13L-KG21"); Debug.Log("SDK激活成功"+ retCode); Logic_LogIn._instance.result_Text.text = "SDK激活成功" + retCode; } catch (Exception e) { Logic_LogIn._instance.result_Text.text = "SDK激活失败" + e.Message; Debug.Log("SDK激活失败" + e.Message); return; } try { //初始化引擎 DetectionMode detectMode = DetectionMode.ASF_DETECT_MODE_IMAGE; //Video模式下检测脸部的角度优先值 //ASF_OrientPriority videoDetectFaceOrientPriority = ASF_OrientPriority.ASF_OP_ALL_OUT; //Image模式下检测脸部的角度优先值 ASF_OrientPriority imageDetectFaceOrientPriority = ASF_OrientPriority.ASF_OP_ALL_OUT; //人脸在图片中所占比例,如果需要调整检测人脸尺寸请修改此值,有效数值为2-32 int detectFaceScaleVal = 16; //最大需要检测的人脸个数 int detectFaceMaxNum = 5; //引擎初始化时需要初始化的检测功能组合 int combinedMask = FaceEngineMask.ASF_FACE_DETECT | FaceEngineMask.ASF_FACERECOGNITION | FaceEngineMask.ASF_AGE | FaceEngineMask.ASF_GENDER | FaceEngineMask.ASF_FACE3DANGLE | FaceEngineMask.ASF_IMAGEQUALITY; //初始化引擎,正常值为0,其他返回值请参考http://ai.arcsoft.com.cn/bbs/forum.php?mod=viewthread&tid=19&_dsign=dbad527e retCode = imageEngine.ASFInitEngine(detectMode, imageDetectFaceOrientPriority, detectFaceScaleVal, detectFaceMaxNum, combinedMask); Debug.Log(retCode==0?"引擎初始化成功" :"初始化失败代码:"+ retCode); Logic_LogIn._instance.result_Text.text = retCode == 0 ? "引擎初始化成功" : "初始化失败代码:" + retCode; ////初始化视频模式下人脸检测引擎 //DetectionMode detectModeVideo = DetectionMode.ASF_DETECT_MODE_VIDEO; //int combinedMaskVideo = FaceEngineMask.ASF_FACE_DETECT | FaceEngineMask.ASF_FACERECOGNITION | FaceEngineMask.ASF_IMAGEQUALITY; } catch (Exception e) { Debug.Log("引擎初始化失败" + e.Message); return; } } /// <summary> /// 选择图片 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// <param name="path"></param> public static ImageInfo ChooseImg(string path) { if (!imageEngine.GetEngineStatus()) { Debug.Log("请先初始化引擎"); return null; } ImageInfo imageInfo = ImageUtil.ReadBMP(ImageUtil.readFromFile(path)); return imageInfo; } /// <summary> /// 人脸检测 /// </summary> /// <param name="image_Info"></param> public static int Face_Detect(Image image) { if (!imageEngine.GetEngineStatus()) { Debug.Log("请先初始化引擎"); return 0; } if (image == null) { Debug.Log("请先选择图片"); return 0; } MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(imageEngine, image); if (multiFaceInfo.faceNum < 1) { Debug.Log("未检测到人脸"); return 0; } else { Debug.Log("检测到" + multiFaceInfo.faceNum + "人"); return multiFaceInfo.faceNum; } } /// <summary> /// 人脸对比 /// </summary> /// <param name="imageInfo_0"></param> /// <param name="imageInfo_1"></param> public static string Face_Compare(string image_0_path, string image_1_path) { string result = ""; if (!imageEngine.GetEngineStatus()) { Debug.Log("请先初始化引擎"); result = "请先初始化引擎"; return result; } if (image_0_path == null || image_1_path == null) { Debug.Log("图片不能为空"); result = "图片不能为空"; return result; } SingleFaceInfo singleFaceInfo = new SingleFaceInfo(); int retCode=0; //人脸特征信息获取 FaceFeature feature_0 = FaceUtil.ExtractFeature(imageEngine, Image.FromFile(image_0_path), out singleFaceInfo,ref retCode); FaceFeature feature_1 = FaceUtil.ExtractFeature(imageEngine, Image.FromFile(image_1_path), out singleFaceInfo,ref retCode); float similarity = 0f; //人脸特征信息对比 imageEngine.ASFFaceFeatureCompare(feature_0, feature_1,out similarity); Debug.Log("两张脸的相似度为:" + similarity); result = similarity.ToString(); return result; } #region 添加内容 /// <summary> /// 人脸对比 /// </summary> /// <param name="imageInfo_0"></param> /// <param name="imageInfo_1"></param> public static float Face_Compare(string image_0_path, byte[] face1) { float similarity = 0f; if (!imageEngine.GetEngineStatus()) { Debug.Log("请先初始化引擎"); return similarity; } if (image_0_path == null || face1 == null) { Debug.Log("对比图片或特征不能为空"); return similarity; } SingleFaceInfo singleFaceInfo = new SingleFaceInfo(); int retCode = 0; //人脸特征信息获取 FaceFeature feature_0 = FaceUtil.ExtractFeature(imageEngine, Image.FromFile(image_0_path), out singleFaceInfo, ref retCode); FaceFeature feature_1 = new FaceFeature(); feature_1.feature = face1; feature_1.featureSize = face1.Length; //人脸特征信息对比 imageEngine.ASFFaceFeatureCompare(feature_0, feature_1, out similarity); Debug.Log("两张脸的相似度为:" + similarity); return similarity; } /// <summary> /// 人脸数据Byte[]返回 /// </summary> /// <param name="srcImage"></param> /// <param name="facedata"></param> public static void Save_FaceData(Image srcImage,ref byte[] facedata) { SingleFaceInfo singleFaceInfo = new SingleFaceInfo(); int retCode = 0; //人脸特征信息获取 FaceFeature face = FaceUtil.ExtractFeature(imageEngine, srcImage, out singleFaceInfo, ref retCode); facedata = face.feature; } public static FaceFeature GetFaceFeature(string path) { SingleFaceInfo singleFaceInfo = new SingleFaceInfo(); int retCode = 0; //人脸特征信息获取 FaceFeature feature = FaceUtil.ExtractFeature(imageEngine, Image.FromFile(path), out singleFaceInfo, ref retCode); return feature; } /// <summary> /// 销毁引擎 /// </summary> public static void DestroyEngine() { imageEngine.ASFUninitEngine(); } #endregion } }
缺少的model类可从官网下载