/// <summary> /// 年龄检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>年龄检测结构体</returns> public static ASF_AgeInfo AgeEstimation(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo) { IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); MemoryUtil.StructureToPtr(multiFaceInfo, pMultiFaceInfo); if (multiFaceInfo.faceNum == 0) { return(new ASF_AgeInfo()); } //人脸信息处理 int retCode = ASFFunctions.ASFProcess(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_AGE); //获取年龄信息 IntPtr pAgeInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_AgeInfo>()); retCode = ASFFunctions.ASFGetAge(pEngine, pAgeInfo); Console.WriteLine("Get Age Result:" + retCode); ASF_AgeInfo ageInfo = MemoryUtil.PtrToStructure <ASF_AgeInfo>(pAgeInfo); //释放内存 MemoryUtil.Free(pMultiFaceInfo); MemoryUtil.Free(pAgeInfo); return(ageInfo); }
/// <summary> /// 获取多个人脸检测结果中面积最大的人脸 /// </summary> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>面积最大的人脸信息</returns> public static ASF_SingleFaceInfo GetMaxFace(ASF_MultiFaceInfo multiFaceInfo) { ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo(); singleFaceInfo.faceRect = new MRECT(); singleFaceInfo.faceOrient = 1; int maxArea = 0; int index = -1; for (int i = 0; i < multiFaceInfo.faceNum; i++) { try { MRECT rect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects + MemoryUtil.SizeOf <MRECT>() * i); int area = (rect.right - rect.left) * (rect.bottom - rect.top); if (maxArea <= area) { maxArea = area; index = i; } } catch (Exception ex) { Console.WriteLine(ex.Message); } } if (index != -1) { singleFaceInfo.faceRect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects + MemoryUtil.SizeOf <MRECT>() * index); singleFaceInfo.faceOrient = MemoryUtil.PtrToStructure <int>(multiFaceInfo.faceOrients + MemoryUtil.SizeOf <int>() * index); } return(singleFaceInfo); }
public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, Image image) { lock (locks) { ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); if (image != null) { if (image == null) { return(multiFaceInfo); } ImageInfo imageInfo = ImageUtil.ReadBMP(image); if (imageInfo == null) { return(multiFaceInfo); } multiFaceInfo = DetectFace(pEngine, imageInfo); MemoryUtil.Free(imageInfo.imgData); return(multiFaceInfo); } else { return(multiFaceInfo); } } }
public List <FaceInfo> ScanFaces(Bitmap bitmap) { List <FaceInfo> singleFaces = new List <FaceInfo>(); if (bitmap == null) { return(null); } //从视频帧中获取 多个人脸的矩形框位置 ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pVideoEngine, bitmap); //将MultiFaceInfo结构体中的数据提取成单人脸数据并放入结构体中 for (int i = 0; i < multiFaceInfo.faceNum; i++) { FaceInfo faceInfo = new FaceInfo(); faceInfo.faceId = MemoryUtil.PtrToStructure <int>(multiFaceInfo.faceID + MemoryUtil.SizeOf <int>() * i); faceInfo.singleFaceInfo.faceRect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects + MemoryUtil.SizeOf <MRECT>() * i); faceInfo.singleFaceInfo.faceOrient = MemoryUtil.PtrToStructure <int>(multiFaceInfo.faceOrients + MemoryUtil.SizeOf <int>() * i); singleFaces.Add(faceInfo); } return(singleFaces); }
/// <summary> /// 从Image图片中提取特征 /// </summary> /// <param name="img"></param> /// <returns></returns> private IntPtr GetFeatureFromImage(Image img) { Image image = img; if (image.Width % 4 != 0) { image = ImageUtil.ScaleImage(image, image.Width - (image.Width % 4), image.Height); } ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pImageEngine, image); if (multiFaceInfo.faceNum > 0) { //裁剪照片到识别人脸的框的大小 MRECT rect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects); image = ImageUtil.CutImage(image, rect.left, rect.top, rect.right, rect.bottom); } //提取人脸特征 ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo(); IntPtr feature = FaceUtil.ExtractFeature(pImageEngine, image, out singleFaceInfo); if (singleFaceInfo.faceRect.left == 0 && singleFaceInfo.faceRect.right == 0) { //messageBox.AppendText("无法提取身份证件照特征...\n"); //无法提取身份证件照特征.. } else { //成功提取到的图像特征值 return(feature); } return(IntPtr.Zero); }
public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, Image image) { lock (locks) { ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); if (image != null) { if (image.Width > 1536 || image.Height > 1536) { image = ImageUtil.ScaleImage(image, 1536, 1536); } else { image = ImageUtil.ScaleImage(image, image.Width, image.Height); } if (image == null) { return(multiFaceInfo); } ImageInfo imageInfo = ImageUtil.ReadBMP(image); if (imageInfo == null) { return(multiFaceInfo); } multiFaceInfo = DetectFace(pEngine, imageInfo); MemoryUtil.Free(imageInfo.imgData); return(multiFaceInfo); } else { return(multiFaceInfo); } } }
/// <summary> /// 提取人脸特征 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>保存人脸特征结构体指针</returns> public static IntPtr ExtractFeature(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out ASF_SingleFaceInfo singleFaceInfo) { singleFaceInfo = new ASF_SingleFaceInfo(); singleFaceInfo.faceRect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects); singleFaceInfo.faceOrient = MemoryUtil.PtrToStructure <int>(multiFaceInfo.faceOrients); IntPtr pSingleFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_SingleFaceInfo>()); // 申请内存,单人脸检测结构体 MemoryUtil.StructureToPtr(singleFaceInfo, pSingleFaceInfo); // 结构体进入内存 IntPtr pFaceFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); // 申请内存,人脸特征结构体 int retCode = ASFFunctions.ASFFaceFeatureExtract(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pSingleFaceInfo, pFaceFeature); // 单人脸特征提取 Console.WriteLine("FR Extract Feature result:" + retCode); // 直接打印结果 if (retCode != 0) // 返回结果非0,即匹配到人脸,释放指针 { // 释放指针 MemoryUtil.Free(pSingleFaceInfo); // 释放单人脸检测结构体指针 MemoryUtil.Free(pFaceFeature); // 释放人脸特征结构体指针 ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); // 声明空人脸特征结构体 IntPtr pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); // 声明空人脸特征结构体指针 MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature); // 将数据从托管对象封送到非托管内存块 return(pEmptyFeature); // 匹配成功,返回空的人脸特征结构体指针 } // 人脸特征feature过滤 ASF_FaceFeature faceFeature = MemoryUtil.PtrToStructure <ASF_FaceFeature>(pFaceFeature);// 将ptr托管的内存转化为结构体对象 int cc = faceFeature.featureSize; var ff = faceFeature.feature; byte[] feature = new byte[faceFeature.featureSize]; MemoryUtil.Copy(faceFeature.feature, feature, 0, faceFeature.featureSize);// source, destination, startIndex, length ASF_FaceFeature localFeature = new ASF_FaceFeature(); localFeature.feature = MemoryUtil.Malloc(feature.Length); // 申请本地人脸特征指针 MemoryUtil.Copy(feature, 0, localFeature.feature, feature.Length); // source, startIndex, destination, length localFeature.featureSize = feature.Length; // 设置本地特征值长度 IntPtr pLocalFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>()); // 申请本地特征值指针空间 MemoryUtil.StructureToPtr(localFeature, pLocalFeature); // T t,IntPtr ptr // 释放指针 MemoryUtil.Free(pSingleFaceInfo); MemoryUtil.Free(pFaceFeature); /******** 特征值feature存入数据库 start **********/ Users users = new Users(); users.Id = SidUtils.sid(); users.Feature = feature; MysqlUtils mysqlUtils = new MysqlUtils(); mysqlUtils.InsertUserFaceFeature(users); /******** 特征值feature存入数据库 end **********/ return(pLocalFeature);// 返回人脸特征 }
/// <summary> /// RGB活体检测 /// </summary> /// <param name="pEngine"></param> /// <param name="imageInfo"></param> /// <param name="multiFaceInfo"></param> /// <returns></returns> public static ASF_LivenessInfo LivenessEstimation(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo) { IntPtr pMultiFaceInfo = MemoryHelper.Malloc(MemoryHelper.SizeOf <ASF_MultiFaceInfo>()); MemoryHelper.StructureToPtr(multiFaceInfo, pMultiFaceInfo); try { if (multiFaceInfo.faceNum == 0) { return(new ASF_LivenessInfo()); } if (multiFaceInfo.faceNum > 1) { ASF_SingleFaceInfo singleFaceInfo = GetMaxFace(multiFaceInfo); ASF_MultiFaceInfo multiFaceInfoNeo = new ASF_MultiFaceInfo(); multiFaceInfoNeo.faceRects = MemoryHelper.Malloc(MemoryHelper.SizeOf <MRECT>()); MemoryHelper.StructureToPtr <MRECT>(singleFaceInfo.faceRect, multiFaceInfoNeo.faceRects); multiFaceInfoNeo.faceOrients = MemoryHelper.Malloc(MemoryHelper.SizeOf <int>()); MemoryHelper.StructureToPtr <int>(singleFaceInfo.faceOrient, multiFaceInfoNeo.faceOrients); multiFaceInfoNeo.faceNum = 1; MemoryHelper.StructureToPtr(multiFaceInfoNeo, pMultiFaceInfo); } //活体信息检测 int retCode = ASFWrapper.ASFProcess(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_LIVENESS); if (retCode == 0) { //获取活体信息 IntPtr pLivenessInfo = MemoryHelper.Malloc(MemoryHelper.SizeOf <ASF_LivenessInfo>()); retCode = ASFWrapper.ASFGetLivenessScore(pEngine, pLivenessInfo); SimplifiedLogHelper.WriteIntoSystemLog(nameof(Afw.Core.Helper.FaceProcessHelper), $"Get Liveness Result:{retCode}"); ASF_LivenessInfo livenessInfo = MemoryHelper.PtrToStructure <ASF_LivenessInfo>(pLivenessInfo); //释放内存 MemoryHelper.Free(pLivenessInfo); return(livenessInfo); } else { return(new ASF_LivenessInfo()); } } catch (Exception ex) { Afw.Core.Helper.SimplifiedLogHelper.WriteIntoSystemLog(nameof(FaceProcessHelper), $"LivenessEstimation Exception => {ex.ToString()}"); } finally { //释放内存 MemoryHelper.Free(pMultiFaceInfo); MemoryHelper.Free(imageInfo.imgData); } return(new ASF_LivenessInfo()); }
/// <summary> /// 人脸检测(PS:检测RGB图像的人脸时,必须保证图像的宽度能被4整除,否则会失败) /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <returns>人脸检测结果</returns> public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, ImageInfo imageInfo) { ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); int retCode = ASFFunctions.ASFDetectFaces(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo); multiFaceInfo = MemoryUtil.PtrToStructure <ASF_MultiFaceInfo>(pMultiFaceInfo); return(multiFaceInfo); }
/// <summary> /// 该接口目前仅支持单人脸IR活体检测(不支持年龄、性别、3D角度的检测),默认取第一张人脸 /// 图像数据以结构体形式传入,对采用更高字节对齐方式的图像兼容性更好 /// </summary> /// <param name="imageFormat">图像格式</param> /// <param name="image">图片</param> /// <param name="multiFaceInfo">人脸框信息</param> /// <param name="combinedMask">检测属性</param> /// <returns>返回0表示正常;返回负数请根据ErrorCodeUtil类注释查看;其他值请在官网-帮助中心查询</returns> public int ASFProcessEx_IR(Image image, MultiFaceInfo multiFaceInfo, int combinedMask, ASF_ImagePixelFormat imageFormat = ASF_ImagePixelFormat.ASVL_PAF_GRAY) { int retCode = -1; if (multiFaceInfo == null) { return(ErrorCodeUtil.MULPTIFACEINFO_IS_NULL); } if (image == null) { return(ErrorCodeUtil.IMAGE_IS_NULL); } ImageInfo imageInfo = new ImageInfo(); imageInfo = ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8.Equals(imageFormat) ? ImageUtil.ReadBMP(image) : ImageUtil.ReadBMP_IR(image); if (imageInfo == null) { return(ErrorCodeUtil.IMAGE_DATA_READ_FAIL); } //转化人脸信息 ASF_MultiFaceInfo multiFaceInfoStruct = new ASF_MultiFaceInfo(); IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); multiFaceInfoStruct.faceNum = multiFaceInfo.faceNum; if (multiFaceInfo.faceNum > 0) { if (multiFaceInfo.faceID != null) { multiFaceInfoStruct.faceID = MemoryUtil.Malloc(multiFaceInfo.faceNum * MemoryUtil.SizeOf <int>()); Marshal.Copy(multiFaceInfo.faceID, 0, multiFaceInfoStruct.faceID, multiFaceInfo.faceNum); } multiFaceInfoStruct.faceOrients = MemoryUtil.Malloc(multiFaceInfo.faceNum * MemoryUtil.SizeOf <int>()); Marshal.Copy(multiFaceInfo.faceOrients, 0, multiFaceInfoStruct.faceOrients, multiFaceInfo.faceNum); multiFaceInfoStruct.faceRects = MemoryUtil.Malloc(MemoryUtil.SizeOf <MRECT>() * multiFaceInfo.faceNum); byte[] allByte = new byte[MemoryUtil.SizeOf <MRECT>() * multiFaceInfo.faceNum]; for (int i = 0; i < multiFaceInfo.faceNum; i++) { byte[] tempBytes = MemoryUtil.StructToBytes(multiFaceInfo.faceRects[i]); tempBytes.CopyTo(allByte, MemoryUtil.SizeOf <MRECT>() * i); } Marshal.Copy(allByte, 0, multiFaceInfoStruct.faceRects, allByte.Length); } MemoryUtil.StructureToPtr(multiFaceInfoStruct, pMultiFaceInfo); ASF_ImageData asfInfoData = CommonUtil.TransImageDataStructByImageInfo(imageInfo); IntPtr pImageInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_ImageData>()); MemoryUtil.StructureToPtr(asfInfoData, pImageInfo); //调用SDK接口 retCode = ASFFunctions.ASFProcessEx_IR(pEngine, pImageInfo, pMultiFaceInfo, combinedMask); //释放内存 MemoryUtil.FreeArray(imageInfo.imgData, multiFaceInfoStruct.faceID, multiFaceInfoStruct.faceOrients, multiFaceInfoStruct.faceRects, pMultiFaceInfo, pImageInfo); return(retCode); }
/// <summary> /// 人脸检测/人脸追踪 /// 图像数据以结构体形式传入,对采用更高字节对齐方式的图像兼容性更好 /// </summary> /// <param name="imageFormat">图片格式</param> /// <param name="image">图片</param> /// <param name="multiFaceInfo">多人脸对象</param> /// <param name="detectModel">检测模式</param> /// <returns>返回0表示正常;返回负数请根据ErrorCodeUtil类注释查看;其他值请在官网-帮助中心查询</returns> public int ASFDetectFacesEx(Image image, out MultiFaceInfo multiFaceInfo, ASF_ImagePixelFormat imageFormat = ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8, ASF_DetectModel detectModel = ASF_DetectModel.ASF_DETECT_MODEL_RGB) { int retCode = -1; multiFaceInfo = new MultiFaceInfo(); if (image == null) { return(ErrorCodeUtil.IMAGE_IS_NULL); } ImageInfo imageInfo = new ImageInfo(); imageInfo = ASF_ImagePixelFormat.ASVL_PAF_RGB24_B8G8R8.Equals(imageFormat) ? ImageUtil.ReadBMP(image) : ImageUtil.ReadBMP_IR(image); if (imageInfo == null) { return(ErrorCodeUtil.IMAGE_DATA_READ_FAIL); } ASF_ImageData asfInfoData = CommonUtil.TransImageDataStructByImageInfo(imageInfo); IntPtr pImageInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_ImageData>()); MemoryUtil.StructureToPtr(asfInfoData, pImageInfo); ASF_MultiFaceInfo multiFaceInfoStruct = new ASF_MultiFaceInfo(); IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); //调用SDK接口 retCode = ASFFunctions.ASFDetectFacesEx(pEngine, pImageInfo, pMultiFaceInfo); if (retCode != 0) { MemoryUtil.FreeArray(imageInfo.imgData, pMultiFaceInfo, pImageInfo); return(retCode); } multiFaceInfoStruct = MemoryUtil.PtrToStructure <ASF_MultiFaceInfo>(pMultiFaceInfo); MemoryUtil.FreeArray(imageInfo.imgData, pMultiFaceInfo, pImageInfo); //转化非托管内存到托管内存 multiFaceInfo.faceNum = multiFaceInfoStruct.faceNum; if (multiFaceInfo.faceNum > 0) { if (multiFaceInfoStruct.faceID != IntPtr.Zero) { multiFaceInfo.faceID = new int[multiFaceInfo.faceNum]; Marshal.Copy(multiFaceInfoStruct.faceID, multiFaceInfo.faceID, 0, multiFaceInfo.faceNum); } multiFaceInfo.faceOrients = new int[multiFaceInfo.faceNum]; Marshal.Copy(multiFaceInfoStruct.faceOrients, multiFaceInfo.faceOrients, 0, multiFaceInfo.faceNum); multiFaceInfo.faceRects = new MRECT[multiFaceInfo.faceNum]; for (int i = 0; i < multiFaceInfo.faceNum; i++) { multiFaceInfo.faceRects[i] = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfoStruct.faceRects + MemoryUtil.SizeOf <MRECT>() * i); } } return(retCode); }
/// <summary> /// 提取人脸特征 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>保存人脸特征结构体指针</returns> public static IntPtr ExtractFaceFeature(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out ASF_SingleFaceInfo singleFaceInfo) { singleFaceInfo = new ASF_SingleFaceInfo(); if (multiFaceInfo.faceRects == null) { ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_FaceFeature>()); UtilToolMemory.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } singleFaceInfo.faceRect = UtilToolMemory.PtrToStructure <MRECT>(multiFaceInfo.faceRects); singleFaceInfo.faceOrient = UtilToolMemory.PtrToStructure <int>(multiFaceInfo.faceOrients); IntPtr pSingleFaceInfo = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_SingleFaceInfo>()); UtilToolMemory.StructureToPtr(singleFaceInfo, pSingleFaceInfo); IntPtr pFaceFeature = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_FaceFeature>()); int retCode = ASFFunctions.ASFFaceFeatureExtract(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pSingleFaceInfo, pFaceFeature); Console.WriteLine("FR Extract Feature result:" + retCode); if (retCode != 0) { //释放指针 UtilToolMemory.Free(pSingleFaceInfo); UtilToolMemory.Free(pFaceFeature); ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_FaceFeature>()); UtilToolMemory.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } //人脸特征feature过滤 ASF_FaceFeature faceFeature = UtilToolMemory.PtrToStructure <ASF_FaceFeature>(pFaceFeature); byte[] feature = new byte[faceFeature.featureSize]; UtilToolMemory.Copy(faceFeature.feature, feature, 0, faceFeature.featureSize); ASF_FaceFeature localFeature = new ASF_FaceFeature(); localFeature.feature = UtilToolMemory.Malloc(feature.Length); UtilToolMemory.Copy(feature, 0, localFeature.feature, feature.Length); localFeature.featureSize = feature.Length; IntPtr pLocalFeature = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_FaceFeature>()); UtilToolMemory.StructureToPtr(localFeature, pLocalFeature); //释放指针 UtilToolMemory.Free(pSingleFaceInfo); UtilToolMemory.Free(pFaceFeature); return(pLocalFeature); }
/// <summary> /// 提取人脸特征 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="image">图像</param> /// <returns>保存人脸特征结构体指针</returns> public static IntPtr ExtractFeature(IntPtr pEngine, Image image, out ASF_SingleFaceInfo singleFaceInfo) { image = ImageUtil.ScaleImage(image, image.Width, image.Height); ImageInfo imageInfo = ImageUtil.ReadBMP(image); ASF_MultiFaceInfo multiFaceInfo = DetectFace(pEngine, imageInfo); singleFaceInfo = new ASF_SingleFaceInfo(); IntPtr pFaceModel = ExtractFeature(pEngine, imageInfo, multiFaceInfo, out singleFaceInfo); MemoryUtil.Free(imageInfo.imgData); return(pFaceModel); }
public static MError Register(IntPtr ptrImageEngine, ref MemberWithFeature member) { var retCode = MError.MERR_UNKNOWN.ToInt(); IntPtr feature = IntPtr.Zero; Image image = null; try { image = Image.FromFile(member.FaceImagePath); if (image.Width % 4 != 0) { image = ImageHelper.ScaleImage(image, image.Width - (image.Width % 4), image.Height); } ASF_MultiFaceInfo multiFaceInfo = FaceProcessHelper.DetectFace(ptrImageEngine, image); if (multiFaceInfo.faceNum > 0) { MRECT rect = MemoryHelper.PtrToStructure <MRECT>(multiFaceInfo.faceRects); image = ImageHelper.CutImage(image, rect.left, rect.top, rect.right, rect.bottom); //提取人脸特征 ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo(); feature = FaceProcessHelper.ExtractFeature(ptrImageEngine, Image.FromFile(member.FaceImagePath), out singleFaceInfo); if (singleFaceInfo.faceRect.left == 0 && singleFaceInfo.faceRect.right == 0) { return(MError.MERR_FSDK_FR_INVALID_FACE_INFO); } else { member.AsfFaceFeature = MemoryHelper.PtrToStructure <ASF_FaceFeature>(feature); } } else { return(MError.MERR_FSDK_FR_INVALID_FACE_INFO); } retCode = MError.MOK.ToInt(); } catch (Exception ex) { Afw.Core.Helper.SimplifiedLogHelper.WriteIntoSystemLog(nameof(MemberEnroll), $"Register Exception:{ex.ToString()}"); } finally { MemoryHelper.Free(feature); image.Dispose(); } return(retCode.ToEnum <MError>()); }
public static ASF_LivenessInfo LivenessEstimationIR(IntPtr pEngine, ImageInfo imageInfo, ASF_SingleFaceInfo singleFaceInfo) { ASF_MultiFaceInfo multiFaceInfoNeo = new ASF_MultiFaceInfo(); multiFaceInfoNeo.faceRects = MemoryHelper.Malloc(MemoryHelper.SizeOf <MRECT>()); MemoryHelper.StructureToPtr <MRECT>(singleFaceInfo.faceRect, multiFaceInfoNeo.faceRects); multiFaceInfoNeo.faceOrients = MemoryHelper.Malloc(MemoryHelper.SizeOf <int>()); MemoryHelper.StructureToPtr <int>(singleFaceInfo.faceOrient, multiFaceInfoNeo.faceOrients); multiFaceInfoNeo.faceNum = 1; ASF_LivenessInfo livenessinfo = LivenessEstimationIR(pEngine, imageInfo, multiFaceInfoNeo); return(livenessinfo); }
/// <summary> /// 单人脸性别检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="image">图片</param> /// <param name="singleFaceInfo">单人脸信息</param> /// <returns>性别估计结果</returns> public static ASF_GenderInfo GenderEstimation(IntPtr pEngine, Image image, ASF_SingleFaceInfo singleFaceInfo) { ImageInfo imageInfo = ImageUtil.ReadBMP(image); ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); multiFaceInfo.faceRects = MemoryUtil.Malloc(MemoryUtil.SizeOf <MRECT>()); MemoryUtil.StructureToPtr <MRECT>(singleFaceInfo.faceRect, multiFaceInfo.faceRects); multiFaceInfo.faceOrients = MemoryUtil.Malloc(MemoryUtil.SizeOf <int>()); MemoryUtil.StructureToPtr <int>(singleFaceInfo.faceOrient, multiFaceInfo.faceOrients); multiFaceInfo.faceNum = 1; ASF_GenderInfo genderInfo = GenderEstimation(pEngine, imageInfo, multiFaceInfo); MemoryUtil.Free(imageInfo.imgData); return(genderInfo); }
/// <summary> /// 单人脸年龄检测 /// </summary> /// <param name="pEngine">人脸识别引擎</param> /// <param name="image">图片</param> /// <param name="singleFaceInfo">单人脸信息</param> /// <returns>年龄检测结果</returns> public static ASF_AgeInfo AgeEstimation(IntPtr pEngine, Image image, ASF_SingleFaceInfo singleFaceInfo) { ImageInfo imageInfo = ImageHelper.ReadBMP(image); ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); multiFaceInfo.faceRects = MemoryHelper.Malloc(MemoryHelper.SizeOf <MRECT>()); MemoryHelper.StructureToPtr <MRECT>(singleFaceInfo.faceRect, multiFaceInfo.faceRects); multiFaceInfo.faceOrients = MemoryHelper.Malloc(MemoryHelper.SizeOf <int>()); MemoryHelper.StructureToPtr <int>(singleFaceInfo.faceOrient, multiFaceInfo.faceOrients); multiFaceInfo.faceNum = 1; ASF_AgeInfo ageInfo = AgeEstimation(pEngine, imageInfo, multiFaceInfo); MemoryHelper.Free(imageInfo.imgData); return(ageInfo); }
/// <summary> /// 提取人脸特征 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>保存人脸特征结构体指针</returns> public static IntPtr ExtractFeature(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out ASF_SingleFaceInfo singleFaceInfo) { singleFaceInfo = new ASF_SingleFaceInfo(); singleFaceInfo.faceRect = MemoryHelper.PtrToStructure <MRECT>(multiFaceInfo.faceRects); singleFaceInfo.faceOrient = MemoryHelper.PtrToStructure <int>(multiFaceInfo.faceOrients); IntPtr pSingleFaceInfo = MemoryHelper.Malloc(MemoryHelper.SizeOf <ASF_SingleFaceInfo>()); MemoryHelper.StructureToPtr(singleFaceInfo, pSingleFaceInfo); IntPtr pFaceFeature = MemoryHelper.Malloc(MemoryHelper.SizeOf <ASF_FaceFeature>()); int retCode = ASFWrapper.ASFFaceFeatureExtract(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pSingleFaceInfo, pFaceFeature); //Console.WriteLine("FR Extract Feature result:" + retCode); SimplifiedLogHelper.WriteIntoSystemLog(nameof(Afw.Core.Helper.FaceProcessHelper), $"FR Extract Feature (4) result:{retCode} => [{retCode.ToEnum<MError>().GetFieldDescription()}]"); if (retCode != 0) { //释放指针 MemoryHelper.Free(pSingleFaceInfo); MemoryHelper.Free(pFaceFeature); ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = MemoryHelper.Malloc(MemoryHelper.SizeOf <ASF_FaceFeature>()); MemoryHelper.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } //人脸特征feature过滤 ASF_FaceFeature faceFeature = MemoryHelper.PtrToStructure <ASF_FaceFeature>(pFaceFeature); byte[] feature = new byte[faceFeature.featureSize]; MemoryHelper.Copy(faceFeature.feature, feature, 0, faceFeature.featureSize); ASF_FaceFeature localFeature = new ASF_FaceFeature(); localFeature.feature = MemoryHelper.Malloc(feature.Length); MemoryHelper.Copy(feature, 0, localFeature.feature, feature.Length); localFeature.featureSize = feature.Length; IntPtr pLocalFeature = MemoryHelper.Malloc(MemoryHelper.SizeOf <ASF_FaceFeature>()); MemoryHelper.StructureToPtr(localFeature, pLocalFeature); //释放指针 MemoryHelper.Free(pSingleFaceInfo); MemoryHelper.Free(pFaceFeature); return(pLocalFeature); }
/// <summary> /// 人脸检测(PS:检测RGB图像的人脸时,必须保证图像的宽度能被4整除,否则会失败) /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <returns>人脸检测结果</returns> public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, ImageInfo imageInfo) { ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); IntPtr pMultiFaceInfo = MemoryHelper.Malloc(MemoryHelper.SizeOf <ASF_MultiFaceInfo>()); int retCode = ASFWrapper.ASFDetectFaces(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo); var errCode = retCode.ToEnum <MError>(); if (errCode == MError.MOK) { multiFaceInfo = MemoryHelper.PtrToStructure <ASF_MultiFaceInfo>(pMultiFaceInfo); } else { throw new FaceDetectException(errCode); } return(multiFaceInfo); }
public static ASF_MultiFaceInfo DetectFaceIR(IntPtr pEngine, Image image) { lock (locks) { ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); if (image != null) { image = ImageHelper.ScaleImage(image, image.Width, image.Height); ImageInfo imageInfo = ImageHelper.ReadGray(image); multiFaceInfo = DetectFace(pEngine, imageInfo); MemoryHelper.Free(imageInfo.imgData); return(multiFaceInfo); } else { return(multiFaceInfo); } } }
//从文件夹的jpg(人脸照片)读数据,测试使用,替换成数据库读取。 private void LoadFaceInformationFromFolderJPG(string folderPath) { string[] files = Directory.GetFiles(folderPath, "*.jpg"); IntPtr pEngine_Load = IntPtr.Zero; FaceAction faceAction = new FaceAction(appID, faceKey, ref pEngine_Load, true); for (int index = 0; index < files.Length; index++) { ImageInfo imageInfor = ArcSoft.Utilities.ImageHelper.ReadBMPFormJPG(files[index]); ASF_MultiFaceInfo individualFaceInfor = new ASF_MultiFaceInfo(); individualFaceInfor = faceAction.DetectMultipleFace(pEngine_Load, imageInfor); List <byte[]> data = faceAction.ExtractAllFeatures(pEngine_Load, imageInfor, individualFaceInfor); if (data.Count == 1) { StaticDataForTestUse.dbFaceInfor.TryAdd(PutFeatureByteIntoFeatureIntPtr(data[0]), Path.GetFileNameWithoutExtension(files[index])); } } FaceAction.ASFUninitEngine(pEngine_Load); }
/// <summary> /// 单人脸性别检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="image">图片</param> /// <param name="singleFaceInfo">单人脸信息</param> /// <returns>性别估计结果</returns> public static ASF_GenderInfo DetectGender(IntPtr pEngine, Image image, ASF_SingleFaceInfo singleFaceInfo) { ImageInfo imageInfo = UtilTool.ReadImage(image); if (imageInfo == null) { return(new ASF_GenderInfo()); } ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); multiFaceInfo.faceRects = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <MRECT>()); UtilToolMemory.StructureToPtr <MRECT>(singleFaceInfo.faceRect, multiFaceInfo.faceRects); multiFaceInfo.faceOrients = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <int>()); UtilToolMemory.StructureToPtr <int>(singleFaceInfo.faceOrient, multiFaceInfo.faceOrients); multiFaceInfo.faceNum = 1; ASF_GenderInfo genderInfo = DetectGender(pEngine, imageInfo, multiFaceInfo); UtilToolMemory.Free(imageInfo.imgData); return(genderInfo); }
/// <summary> /// 获取人脸信息列表 /// </summary> /// <param name="pEngine"></param> /// <param name="bitmap"></param> /// <returns></returns> public static List <FaceInfoModel> GetFaceInfos(IntPtr pEngine, Image bitmap) { List <FaceInfoModel> listRet = new List <FaceInfoModel>(); try { List <int> AgeList = new List <int>(); List <int> GenderList = new List <int>(); //检测人脸,得到Rect框 ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pEngine, bitmap); MultiFaceModel multiFaceModel = new MultiFaceModel(multiFaceInfo); //人脸信息处理 ImageInfo imageInfo = ImageUtil.ReadBMP(bitmap); int retCode = ASFFunctions.ASFProcess(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, ref multiFaceInfo, FaceEngineMask.ASF_AGE | FaceEngineMask.ASF_GENDER); //获取年龄信息 ASF_AgeInfo ageInfo = new ASF_AgeInfo(); retCode = ASFFunctions.ASFGetAge(pEngine, ref ageInfo); AgeList = ageInfo.PtrToAgeArray(ageInfo.ageArray, ageInfo.num); //获取性别信息 ASF_GenderInfo genderInfo = new ASF_GenderInfo(); retCode = ASFFunctions.ASFGetGender(pEngine, ref genderInfo); GenderList = genderInfo.PtrToGenderArray(genderInfo.genderArray, genderInfo.num); for (int i = 0; i < multiFaceInfo.faceNum; i++) { FaceInfoModel faceInfo = new FaceInfoModel(); faceInfo.age = AgeList[i]; faceInfo.gender = GenderList[i]; faceInfo.faceRect = multiFaceModel.FaceInfoList[i].faceRect; faceInfo.feature = ExtractFeature(pEngine, bitmap, multiFaceModel.FaceInfoList[i]);//提取单人脸特征 faceInfo.faceOrient = multiFaceModel.FaceInfoList[i].faceOrient; listRet.Add(faceInfo); } return(listRet);//返回多人脸信息 } catch { return(listRet); } }
public List <FaceInfo> ScanFaces(Bitmap bitmap) { List <FaceInfo> singleFaces = new List <FaceInfo>(); if (bitmap == null) { return(null); } //从视频帧中获取 多个人脸的矩形框位置 ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pImageEngine, bitmap); //如果识别出人脸,且当前只有一个人脸 if (multiFaceInfo.faceNum == 1) { //将MultiFaceInfo结构体中的数据提取成单人脸数据并放入结构体中 for (int i = 0; i < multiFaceInfo.faceNum; i++) { FaceInfo faceInfo = new FaceInfo(); faceInfo.singleFaceInfo.faceRect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects + MemoryUtil.SizeOf <MRECT>() * i); faceInfo.singleFaceInfo.faceOrient = MemoryUtil.PtrToStructure <int>(multiFaceInfo.faceOrients + MemoryUtil.SizeOf <int>() * i); singleFaces.Add(faceInfo); } } else { LoggerService.logger.Info($"当前图片中含有多个人脸或没有人脸,请重新选择单人图片,进行特征提取"); if (bitmap != null) { bitmap.Dispose(); Console.WriteLine("释放成功"); } } return(singleFaces); }
/// <summary> /// 人脸检测 /// 检测RGB图像的人脸时,必须保证图像的宽度能被4整除,否则会失败 /// </summary> /// <param name="pEngine">引擎</param> /// <param name="imageInfo">图像数据</param> /// <returns></returns> public static ASF_MultiFaceInfo DetectFace(IntPtr pEngine, ImageInfo imageInfo) { //创建多张人脸的数据结构体 ASF_MultiFaceInfo multiFaceInfo = new ASF_MultiFaceInfo(); //创建一个指针可以指向MultiFaceInfo结构 IntPtr pMultiFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_MultiFaceInfo>()); int retCode = ASFFunctions.ASFDetectFaces(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo); //当人脸识别错误,则释放内存,返回一个默认的结构 if (retCode != 0) { MemoryUtil.Free(pMultiFaceInfo); pMultiFaceInfo = IntPtr.Zero; return(multiFaceInfo); } //将从C++程序集得到的多人脸结构内存转义成C#的多人脸结构体中 multiFaceInfo = MemoryUtil.PtrToStructure <ASF_MultiFaceInfo>(pMultiFaceInfo); MemoryUtil.Free(pMultiFaceInfo); pMultiFaceInfo = IntPtr.Zero; return(multiFaceInfo); }
/// <summary> /// 提取人脸特征 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="image">图像</param> /// <returns>保存人脸特征结构体指针</returns> public static IntPtr ExtractFaceFeature(IntPtr pEngine, Image image, out ASF_SingleFaceInfo singleFaceInfo) { if (image.Width > 1536 || image.Height > 1536) { image = UtilTool.ScaleImage(image, 1536, 1536); } else { image = UtilTool.ScaleImage(image, image.Width, image.Height); } if (image == null) { singleFaceInfo = new ASF_SingleFaceInfo(); ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_FaceFeature>()); UtilToolMemory.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } ImageInfo imageInfo = UtilTool.ReadImage(image); if (imageInfo == null) { singleFaceInfo = new ASF_SingleFaceInfo(); ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_FaceFeature>()); UtilToolMemory.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } ASF_MultiFaceInfo multiFaceInfo = DetectFace(pEngine, imageInfo); singleFaceInfo = new ASF_SingleFaceInfo(); IntPtr pFaceModel = ExtractFaceFeature(pEngine, imageInfo, multiFaceInfo, out singleFaceInfo); UtilToolMemory.Free(imageInfo.imgData); return(pFaceModel); }
/// <summary> /// 人脸库图片选择按钮事件 /// </summary> private void ChooseMultiImg(object sender, EventArgs e) { lock (locker) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Title = "选择图片"; openFileDialog.Filter = "图片文件|*.bmp;*.jpg;*.jpeg;*.png"; openFileDialog.Multiselect = true; openFileDialog.FileName = string.Empty; if (openFileDialog.ShowDialog() == DialogResult.OK) { List <string> imagePathListTemp = new List <string>(); var numStart = imagePathList.Count; int isGoodImage = 0; //保存图片路径并显示 string[] fileNames = openFileDialog.FileNames; for (int i = 0; i < fileNames.Length; i++) { imagePathListTemp.Add(fileNames[i]); } //人脸检测以及提取人脸特征 ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { //禁止点击按钮 Invoke(new Action(delegate { chooseMultiImgBtn.Enabled = false; matchBtn.Enabled = false; btnClearFaceList.Enabled = false; chooseImgBtn.Enabled = false; })); //人脸检测和剪裁 for (int i = 0; i < imagePathListTemp.Count; i++) { Image image = Image.FromFile(imagePathListTemp[i]); ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pEngine, image); if (multiFaceInfo.faceNum > 0) { imagePathList.Add(imagePathListTemp[i]); MRECT rect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects); image = ImageUtil.CutImage(image, rect.left, rect.top, rect.right, rect.bottom); } else { continue; } this.Invoke(new Action(delegate { if (image == null) { image = Image.FromFile(imagePathListTemp[i]); } imageLists.Images.Add(imagePathListTemp[i], image); imageList.Items.Add((numStart + isGoodImage) + "号", imagePathListTemp[i]); isGoodImage += 1; image = null; })); } //提取人脸特征 for (int i = numStart; i < imagePathList.Count; i++) { ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo(); IntPtr feature = FaceUtil.ExtractFeature(pEngine, Image.FromFile(imagePathList[i]), out singleFaceInfo); this.Invoke(new Action(delegate { if (singleFaceInfo.faceRect.left == 0 && singleFaceInfo.faceRect.right == 0) { AppendText(string.Format("{0}号未检测到人脸\r\n", i)); } else { AppendText(string.Format("已提取{0}号人脸特征值,[left:{1},right:{2},top:{3},bottom:{4},orient:{5}]\r\n", i, singleFaceInfo.faceRect.left, singleFaceInfo.faceRect.right, singleFaceInfo.faceRect.top, singleFaceInfo.faceRect.bottom, singleFaceInfo.faceOrient)); imagesFeatureList.Add(feature); } })); } //imagePathList.AddRange(imagePathListTemp); //允许点击按钮 Invoke(new Action(delegate { chooseMultiImgBtn.Enabled = true; matchBtn.Enabled = true; btnClearFaceList.Enabled = true; chooseImgBtn.Enabled = true; })); })); } } }
/// <summary> /// “选择识别图片”按钮事件 /// </summary> private void ChooseImg(object sender, EventArgs e) { lblCompareInfo.Text = ""; if (pEngine == IntPtr.Zero) { chooseMultiImgBtn.Enabled = false; matchBtn.Enabled = false; btnClearFaceList.Enabled = false; chooseImgBtn.Enabled = false; MessageBox.Show("请先初始化引擎!"); return; } OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Title = "选择图片"; openFileDialog.Filter = "图片文件|*.bmp;*.jpg;*.jpeg;*.png"; openFileDialog.Multiselect = false; openFileDialog.FileName = string.Empty; if (openFileDialog.ShowDialog() == DialogResult.OK) { DateTime detectStartTime = DateTime.Now; AppendText(string.Format("------------------------------开始检测,时间:{0}------------------------------\n", detectStartTime.ToString("yyyy-MM-dd HH:mm:ss:ms"))); image1Path = openFileDialog.FileName; //获取文件,拒绝过大的图片 FileInfo fileInfo = new FileInfo(image1Path); long maxSize = 1024 * 1024 * 2; if (fileInfo.Length > maxSize) { MessageBox.Show("图像文件最大为2MB,请压缩后再导入!"); AppendText(string.Format("------------------------------检测结束,时间:{0}------------------------------\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms"))); AppendText("\n"); return; } Image srcImage = Image.FromFile(image1Path); //调整图像宽度,需要宽度为4的倍数 srcImage = ImageUtil.ScaleImage(srcImage, picImageCompare.Width, picImageCompare.Height); //调整图片数据,非常重要 ImageInfo imageInfo = ImageUtil.ReadBMP(srcImage); //人脸检测 ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pEngine, imageInfo); //年龄检测 int retCode_Age = -1; ASF_AgeInfo ageInfo = FaceUtil.AgeEstimation(pEngine, imageInfo, multiFaceInfo, out retCode_Age); //性别检测 int retCode_Gender = -1; ASF_GenderInfo genderInfo = FaceUtil.GenderEstimation(pEngine, imageInfo, multiFaceInfo, out retCode_Gender); //3DAngle检测 int retCode_3DAngle = -1; ASF_Face3DAngle face3DAngleInfo = FaceUtil.Face3DAngleDetection(pEngine, imageInfo, multiFaceInfo, out retCode_3DAngle); MemoryUtil.Free(imageInfo.imgData); if (multiFaceInfo.faceNum < 1) { image1Feature = IntPtr.Zero; picImageCompare.Image = srcImage; AppendText(string.Format("{0} - 未检测出人脸!\n\n", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"))); AppendText(string.Format("------------------------------检测结束,时间:{0}------------------------------\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms"))); AppendText("\n"); return; } MRECT temp = new MRECT(); int ageTemp = 0; int genderTemp = 0; int rectTemp = 0; //标记出检测到的人脸 for (int i = 0; i < multiFaceInfo.faceNum; i++) { MRECT rect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects + MemoryUtil.SizeOf <MRECT>() * i); int orient = MemoryUtil.PtrToStructure <int>(multiFaceInfo.faceOrients + MemoryUtil.SizeOf <int>() * i); int age = 0; if (retCode_Age != 0) { AppendText(string.Format("年龄检测失败,返回{0}!\n\n", retCode_Age)); } else { age = MemoryUtil.PtrToStructure <int>(ageInfo.ageArray + MemoryUtil.SizeOf <int>() * i); } int gender = -1; if (retCode_Gender != 0) { AppendText(string.Format("性别检测失败,返回{0}!\n\n", retCode_Gender)); } else { gender = MemoryUtil.PtrToStructure <int>(genderInfo.genderArray + MemoryUtil.SizeOf <int>() * i); } int face3DStatus = -1; float roll = 0f; float pitch = 0f; float yaw = 0f; if (retCode_3DAngle != 0) { AppendText(string.Format("3DAngle检测失败,返回{0}!\n\n", retCode_3DAngle)); } else { //角度状态 非0表示人脸不可信 face3DStatus = MemoryUtil.PtrToStructure <int>(face3DAngleInfo.status + MemoryUtil.SizeOf <int>() * i); //roll为侧倾角,pitch为俯仰角,yaw为偏航角 roll = MemoryUtil.PtrToStructure <float>(face3DAngleInfo.roll + MemoryUtil.SizeOf <float>() * i); pitch = MemoryUtil.PtrToStructure <float>(face3DAngleInfo.pitch + MemoryUtil.SizeOf <float>() * i); yaw = MemoryUtil.PtrToStructure <float>(face3DAngleInfo.yaw + MemoryUtil.SizeOf <float>() * i); } int rectWidth = rect.right - rect.left; int rectHeight = rect.bottom - rect.top; //查找最大人脸 if (rectWidth * rectHeight > rectTemp) { rectTemp = rectWidth * rectHeight; temp = rect; ageTemp = age; genderTemp = gender; } //srcImage = ImageUtil.MarkRectAndString(srcImage, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, age, gender); AppendText(string.Format("{0} - 人脸坐标:[left:{1},top:{2},right:{3},bottom:{4},orient:{5},roll:{6},pitch:{7},yaw:{8},status:{11}] Age:{9} Gender:{10}\n", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), rect.left, rect.top, rect.right, rect.bottom, orient, roll, pitch, yaw, age, (gender >= 0 ? gender.ToString() : ""), face3DStatus)); } srcImage = ImageUtil.MarkRectAndString(srcImage, temp.left, temp.top, temp.right - temp.left, temp.bottom - temp.top, ageTemp, genderTemp); AppendText(string.Format("{0} - 人脸数量:{1}\n\n", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), multiFaceInfo.faceNum)); //显示标记后的图像 picImageCompare.Image = srcImage; DateTime detectEndTime = DateTime.Now; AppendText(string.Format("------------------------------检测结束,时间:{0}------------------------------\n", detectEndTime.ToString("yyyy-MM-dd HH:mm:ss:ms"))); AppendText("\n"); ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo(); //提取人脸特征 image1Feature = FaceUtil.ExtractFeature(pEngine, srcImage, out singleFaceInfo); //清空上次的匹配结果 for (int i = 0; i < imagesFeatureList.Count; i++) { imageList.Items[i].Text = string.Format("{0}号", i); } } }
/// <summary> /// 红外活体检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">活体检测结果</param> /// <returns>保存活体检测结果结构体</returns> public static ASF_LivenessInfo LivenessInfo_IR(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out int retCode) { IntPtr pMultiFaceInfo = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_MultiFaceInfo>()); UtilToolMemory.StructureToPtr(multiFaceInfo, pMultiFaceInfo); if (multiFaceInfo.faceNum == 0) { retCode = -1; //释放内存 UtilToolMemory.Free(pMultiFaceInfo); return(new ASF_LivenessInfo()); } try { //人脸信息处理 retCode = ASFFunctions.ASFProcess_IR(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_IR_LIVENESS); if (retCode == 0) { //获取活体检测结果 IntPtr pLivenessInfo = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_LivenessInfo>()); retCode = ASFFunctions.ASFGetLivenessScore_IR(pEngine, pLivenessInfo); Console.WriteLine("Get Liveness Result:" + retCode); ASF_LivenessInfo livenessInfo = UtilToolMemory.PtrToStructure <ASF_LivenessInfo>(pLivenessInfo); //释放内存 UtilToolMemory.Free(pMultiFaceInfo); UtilToolMemory.Free(pLivenessInfo); return(livenessInfo); } else { //释放内存 UtilToolMemory.Free(pMultiFaceInfo); return(new ASF_LivenessInfo()); } } catch { retCode = -1; //释放内存 UtilToolMemory.Free(pMultiFaceInfo); return(new ASF_LivenessInfo()); } }
/// <summary> /// 人脸3D角度检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>保存人脸3D角度检测结果结构体</returns> public static ASF_Face3DAngle DetectFace3DAngle(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out int retCode) { IntPtr pMultiFaceInfo = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_MultiFaceInfo>()); UtilToolMemory.StructureToPtr(multiFaceInfo, pMultiFaceInfo); if (multiFaceInfo.faceNum == 0) { retCode = -1; return(new ASF_Face3DAngle()); } //人脸信息处理 retCode = ASFFunctions.ASFProcess(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_FACE3DANGLE); if (retCode == 0) { //获取人脸3D角度 IntPtr pFace3DAngleInfo = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_Face3DAngle>()); retCode = ASFFunctions.ASFGetFace3DAngle(pEngine, pFace3DAngleInfo); Console.WriteLine("Get Face3D Angle Result:" + retCode); ASF_Face3DAngle face3DAngle = UtilToolMemory.PtrToStructure <ASF_Face3DAngle>(pFace3DAngleInfo); //释放内存 UtilToolMemory.Free(pMultiFaceInfo); UtilToolMemory.Free(pFace3DAngleInfo); return(face3DAngle); } else { return(new ASF_Face3DAngle()); } }