/// <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()); } }
/// <summary> /// 性别检测 /// </summary> /// <param name="pEngine">引擎Handle</param> /// <param name="imageInfo">图像数据</param> /// <param name="multiFaceInfo">人脸检测结果</param> /// <returns>保存性别检测结果结构体</returns> public static ASF_GenderInfo DetectGender(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo, out int retCode) { retCode = -1; IntPtr pMultiFaceInfo = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_MultiFaceInfo>()); UtilToolMemory.StructureToPtr(multiFaceInfo, pMultiFaceInfo); if (multiFaceInfo.faceNum == 0) { return(new ASF_GenderInfo()); } //人脸信息处理 retCode = ASFFunctions.ASFProcess(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo, FaceEngineMask.ASF_GENDER); if (retCode == 0) { //获取性别信息 IntPtr pGenderInfo = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_GenderInfo>()); retCode = ASFFunctions.ASFGetGender(pEngine, pGenderInfo); Console.WriteLine("Get Gender Result:" + retCode); ASF_GenderInfo genderInfo = UtilToolMemory.PtrToStructure <ASF_GenderInfo>(pGenderInfo); //释放内存 UtilToolMemory.Free(pMultiFaceInfo); UtilToolMemory.Free(pGenderInfo); return(genderInfo); } else { return(new ASF_GenderInfo()); } }
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 = UtilTool.ReadImage(image); if (imageInfo == null) { return(multiFaceInfo); } multiFaceInfo = DetectFace(pEngine, imageInfo); UtilToolMemory.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 ASF_AgeInfo DetectAge(IntPtr pEngine, ImageInfo imageInfo, ASF_MultiFaceInfo multiFaceInfo) { IntPtr pMultiFaceInfo = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_MultiFaceInfo>()); UtilToolMemory.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 = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_AgeInfo>()); retCode = ASFFunctions.ASFGetAge(pEngine, pAgeInfo); Console.WriteLine("Get Age Result:" + retCode); ASF_AgeInfo ageInfo = UtilToolMemory.PtrToStructure <ASF_AgeInfo>(pAgeInfo); //释放内存 UtilToolMemory.Free(pMultiFaceInfo); UtilToolMemory.Free(pAgeInfo); return(ageInfo); }
/// <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> /// 人脸检测(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 = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_MultiFaceInfo>()); int retCode = ASFFunctions.ASFDetectFaces(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pMultiFaceInfo); if (retCode != 0) { UtilToolMemory.Free(pMultiFaceInfo); return(multiFaceInfo); } multiFaceInfo = UtilToolMemory.PtrToStructure <ASF_MultiFaceInfo>(pMultiFaceInfo); UtilToolMemory.Free(pMultiFaceInfo); return(multiFaceInfo); }
/// <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> /// 单人脸性别检测 /// </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">引擎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> /// <param name="pEngine">人脸识别引擎</param> /// <param name="image">图片</param> /// <param name="singleFaceInfo">单人脸信息</param> /// <returns>单人脸特征</returns> public static IntPtr ExtractFaceFeature(IntPtr pEngine, Image image, ASF_SingleFaceInfo singleFaceInfo) { ImageInfo imageInfo = UtilTool.ReadImage(image); if (imageInfo == null) { ASF_FaceFeature emptyFeature = new ASF_FaceFeature(); IntPtr pEmptyFeature = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_FaceFeature>()); UtilToolMemory.StructureToPtr(emptyFeature, pEmptyFeature); return(pEmptyFeature); } IntPtr pSingleFaceInfo = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_SingleFaceInfo>()); UtilToolMemory.StructureToPtr(singleFaceInfo, pSingleFaceInfo); IntPtr pFaceFeature = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_FaceFeature>()); int retCode = -1; try { retCode = ASFFunctions.ASFFaceFeatureExtract(pEngine, imageInfo.width, imageInfo.height, imageInfo.format, imageInfo.imgData, pSingleFaceInfo, pFaceFeature); } catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("FR Extract Feature result:" + retCode); if (retCode != 0) { //释放指针 UtilToolMemory.Free(pSingleFaceInfo); UtilToolMemory.Free(pFaceFeature); UtilToolMemory.Free(imageInfo.imgData); 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); UtilToolMemory.Free(imageInfo.imgData); return(pLocalFeature); }
/// <summary> /// RGB摄像头Paint事件,同步RGB人脸框,对比人脸框后进行IR活体检测 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void IrVideoSource_Paint(object sender, PaintEventArgs e) { if (isDoubleShot && FRC.MainView._irVideoSource.IsRunning) { //如果双摄,且IR摄像头工作,获取IR摄像头图片 Bitmap irBitmap = FRC.MainView._irVideoSource.GetCurrentVideoFrame(); if (irBitmap == null) { return; } //得到Rect MRECT rect = new MRECT(); lock (rectLock) { rect = allRect; } float irOffsetX = FRC.MainView._irVideoSource.Width * 1f / irBitmap.Width; float irOffsetY = FRC.MainView._irVideoSource.Height * 1f / irBitmap.Height; float offsetX = FRC.MainView._irVideoSource.Width * 1f / FRC.MainView._rgbVideoSource.Width; float offsetY = FRC.MainView._irVideoSource.Height * 1f / FRC.MainView._rgbVideoSource.Height; //检测IR摄像头下最大人脸 Graphics g = e.Graphics; float x = rect.left * offsetX; float width = rect.right * offsetX - x; float y = rect.top * offsetY; float height = rect.bottom * offsetY - y; //根据Rect进行画框 g.DrawRectangle(Pens.Red, x, y, width, height); if (trackIRUnit.message != "" && x > 0 && y > 0) { //将上一帧检测结果显示到页面上 g.DrawString(trackIRUnit.message, font, trackIRUnit.message.Contains("活体") ? blueBrush : yellowBrush, x, y - 15); } //保证只检测一帧,防止页面卡顿以及出现其他内存被占用情况 if (isIRLock == false) { isIRLock = true; //异步处理提取特征值和比对,不然页面会比较卡 ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { if (rect.left != 0 && rect.right != 0 && rect.top != 0 && rect.bottom != 0) { bool isLiveness = false; try { //得到当前摄像头下的图片 if (irBitmap != null) { //检测人脸,得到Rect框 ASF_MultiFaceInfo irMultiFaceInfo = UtilToolFace.DetectFace(pVideoIRImageEngine, irBitmap); if (irMultiFaceInfo.faceNum <= 0) { return; } //得到最大人脸 ASF_SingleFaceInfo irMaxFace = UtilToolFace.GetMaxFace(irMultiFaceInfo); //得到Rect MRECT irRect = irMaxFace.faceRect; //判断RGB图片检测的人脸框与IR摄像头检测的人脸框偏移量是否在误差允许范围内 if (JudgeInAllowErrorRange(rect.left * offsetX / irOffsetX, irRect.left) && JudgeInAllowErrorRange(rect.right * offsetX / irOffsetX, irRect.right) && JudgeInAllowErrorRange(rect.top * offsetY / irOffsetY, irRect.top) && JudgeInAllowErrorRange(rect.bottom * offsetY / irOffsetY, irRect.bottom)) { int retCode_Liveness = -1; //将图片进行灰度转换,然后获取图片数据 ImageInfo irImageInfo = UtilTool.ReadBMP_IR(irBitmap); if (irImageInfo == null) { return; } //IR活体检测 ASF_LivenessInfo liveInfo = UtilToolFace.LivenessInfo_IR(pVideoIRImageEngine, irImageInfo, irMultiFaceInfo, out retCode_Liveness); //判断检测结果 if (retCode_Liveness == 0 && liveInfo.num > 0) { int isLive = UtilToolMemory.PtrToStructure <int>(liveInfo.isLive); isLiveness = (isLive == 1) ? true : false; } if (irImageInfo != null) { UtilToolMemory.Free(irImageInfo.imgData); } } } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { trackIRUnit.message = string.Format("IR{0}", isLiveness ? "活体" : "假体"); if (irBitmap != null) { irBitmap.Dispose(); } isIRLock = false; } } else { trackIRUnit.message = string.Empty; } isIRLock = false; })); } } }
/// <summary> /// RGB摄像头Paint事件,图像显示到窗体上,得到每一帧图像,并进行处理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void VideoSource_Paint(object sender, PaintEventArgs e) { if (FRC.MainView._rgbVideoSource.IsRunning) { //得到当前RGB摄像头下的图片 Bitmap bitmap = FRC.MainView._rgbVideoSource.GetCurrentVideoFrame(); if (bitmap == null) { return; } //检测人脸,得到Rect框 ASF_MultiFaceInfo multiFaceInfo = UtilToolFace.DetectFace(pVideoEngine, bitmap); //得到最大人脸 ASF_SingleFaceInfo maxFace = UtilToolFace.GetMaxFace(multiFaceInfo); //得到Rect MRECT rect = maxFace.faceRect; //检测RGB摄像头下最大人脸 Graphics g = e.Graphics; float offsetX = FRC.MainView._rgbVideoSource.Width * 1f / bitmap.Width; float offsetY = FRC.MainView._rgbVideoSource.Height * 1f / bitmap.Height; float x = rect.left * offsetX; float width = rect.right * offsetX - x; float y = rect.top * offsetY; float height = rect.bottom * offsetY - y; //根据Rect进行画框 g.DrawRectangle(Pens.Red, x, y, width, height); if (trackRGBUnit.message != "" && x > 0 && y > 0) { //将上一帧检测结果显示到页面上 g.DrawString(trackRGBUnit.message, font, trackRGBUnit.message.Contains("活体") ? blueBrush : yellowBrush, x, y - 15); } //保证只检测一帧,防止页面卡顿以及出现其他内存被占用情况 if (isRGBLock == false) { isRGBLock = true; //异步处理提取特征值和比对,不然页面会比较卡 ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { if (rect.left != 0 && rect.right != 0 && rect.top != 0 && rect.bottom != 0) { try { lock (rectLock) { allRect.left = (int)(rect.left * offsetX); allRect.top = (int)(rect.top * offsetY); allRect.right = (int)(rect.right * offsetX); allRect.bottom = (int)(rect.bottom * offsetY); } bool isLiveness = false; //调整图片数据,非常重要 ImageInfo imageInfo = UtilTool.ReadImage(bitmap); if (imageInfo == null) { return; } int retCode_Liveness = -1; //RGB活体检测 ASF_LivenessInfo liveInfo = UtilToolFace.LivenessInfo_RGB(pVideoRGBImageEngine, imageInfo, multiFaceInfo, out retCode_Liveness); //判断检测结果 if (retCode_Liveness == 0 && liveInfo.num > 0) { int isLive = UtilToolMemory.PtrToStructure <int>(liveInfo.isLive); isLiveness = (isLive == 1) ? true : false; } if (imageInfo != null) { UtilToolMemory.Free(imageInfo.imgData); } if (isLiveness) { //提取人脸特征 IntPtr feature = UtilToolFace.ExtractFaceFeature(pVideoRGBImageEngine, bitmap, maxFace); float similarity = 0f; //得到比对结果 int result = CompareFeature(feature, out similarity); UtilToolMemory.Free(feature); if (result > -1) { //将比对结果放到显示消息中,用于最新显示 trackRGBUnit.message = string.Format(" {0}号 {1},{2}", result, similarity, string.Format("RGB{0}", isLiveness ? "活体" : "假体")); } else { //显示消息 trackRGBUnit.message = string.Format("RGB{0}", isLiveness ? "活体" : "假体"); } } else { //显示消息 trackRGBUnit.message = string.Format("RGB{0}", isLiveness ? "活体" : "假体"); } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { if (bitmap != null) { bitmap.Dispose(); } isRGBLock = false; } } else { lock (rectLock) { allRect.left = 0; allRect.top = 0; allRect.right = 0; allRect.bottom = 0; } } isRGBLock = false; })); } } }
/// <summary> /// “选择图片识别” /// </summary> public void ChooseImgeDistinguish(bool IsOffline) { //判断引擎是否初始化成功 if (pImageEngine == IntPtr.Zero) { //禁用相关功能按钮 FRC.MainVM.IsSIIBtnEnable = false; FRC.MainVM.IsPGIBtnEnable = false; //ControlsEnable(false, chooseMultiImgBtn, matchBtn, btnClearFaceList, chooseImgBtn); MessageBox.Show("请先初始化引擎!"); return; } List <string> imagePathList = ImportImages(IsOffline, false);//单张照片 if (imagePathList.Count <= 0) { return; } string selectedImagePath = imagePathList[0]; DateTime detectStartTime = DateTime.Now; AppendText(string.Format("------------------------------开始检测,时间:{0}------------------------------\n", detectStartTime.ToString("yyyy-MM-dd HH:mm:ss:ms"))); //获取文件,拒绝过大的图片 FileInfo fileInfo = new FileInfo(selectedImagePath); 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 = UtilTool.ReadImageFromFile(selectedImagePath); if (srcImage == null) { MessageBox.Show("图像数据获取失败,请稍后重试!"); AppendText(string.Format("------------------------------检测结束,时间:{0}------------------------------\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms"))); AppendText("\n"); return; } if (srcImage.Width > 1536 || srcImage.Height > 1536) { srcImage = UtilTool.ScaleImage(srcImage, 1536, 1536); } if (srcImage == null) { MessageBox.Show("图像数据获取失败,请稍后重试!"); AppendText(string.Format("------------------------------检测结束,时间:{0}------------------------------\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms"))); AppendText("\n"); return; } //调整图像宽度,需要宽度为4的倍数 if (srcImage.Width % 4 != 0) { srcImage = UtilTool.ScaleImage(srcImage, srcImage.Width - (srcImage.Width % 4), srcImage.Height); } //调整图片数据,非常重要 ImageInfo imageInfo = UtilTool.ReadImage(srcImage); if (imageInfo == null) { MessageBox.Show("图像数据获取失败,请稍后重试!"); AppendText(string.Format("------------------------------检测结束,时间:{0}------------------------------\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms"))); AppendText("\n"); return; } //人脸检测 ASF_MultiFaceInfo multiFaceInfo = UtilToolFace.DetectFace(pImageEngine, imageInfo); //年龄检测 int retCode_Age = -1; ASF_AgeInfo ageInfo = UtilToolFace.DetectAge(pImageEngine, imageInfo, multiFaceInfo, out retCode_Age); //性别检测 int retCode_Gender = -1; ASF_GenderInfo genderInfo = UtilToolFace.DetectGender(pImageEngine, imageInfo, multiFaceInfo, out retCode_Gender); //3DAngle检测 int retCode_3DAngle = -1; ASF_Face3DAngle face3DAngleInfo = UtilToolFace.DetectFace3DAngle(pImageEngine, imageInfo, multiFaceInfo, out retCode_3DAngle); UtilToolMemory.Free(imageInfo.imgData); if (multiFaceInfo.faceNum < 1) { srcImage = UtilTool.ScaleImage(srcImage, (int)FRC.FIView._faceIdentificationImageBox.Width, (int)FRC.FIView._faceIdentificationImageBox.Height); ImageFeature = IntPtr.Zero; FRC.FIView._faceIdentificationImageBox.Source = UtilTool.BitmapToBitmapImage(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 = UtilToolMemory.PtrToStructure <MRECT>(multiFaceInfo.faceRects + UtilToolMemory.SizeOf <MRECT>() * i); int orient = UtilToolMemory.PtrToStructure <int>(multiFaceInfo.faceOrients + UtilToolMemory.SizeOf <int>() * i); int age = 0; if (retCode_Age != 0) { AppendText(string.Format("年龄检测失败,返回{0}!\n\n", retCode_Age)); } else { age = UtilToolMemory.PtrToStructure <int>(ageInfo.ageArray + UtilToolMemory.SizeOf <int>() * i); } int gender = -1; if (retCode_Gender != 0) { AppendText(string.Format("性别检测失败,返回{0}!\n\n", retCode_Gender)); } else { gender = UtilToolMemory.PtrToStructure <int>(genderInfo.genderArray + UtilToolMemory.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 = UtilToolMemory.PtrToStructure <int>(face3DAngleInfo.status + UtilToolMemory.SizeOf <int>() * i); //roll为侧倾角,pitch为俯仰角,yaw为偏航角 roll = UtilToolMemory.PtrToStructure <float>(face3DAngleInfo.roll + UtilToolMemory.SizeOf <float>() * i); pitch = UtilToolMemory.PtrToStructure <float>(face3DAngleInfo.pitch + UtilToolMemory.SizeOf <float>() * i); yaw = UtilToolMemory.PtrToStructure <float>(face3DAngleInfo.yaw + UtilToolMemory.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; } 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)); } AppendText(string.Format("{0} - 人脸数量:{1}\n\n", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), multiFaceInfo.faceNum)); 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(); //提取人脸特征 ImageFeature = UtilToolFace.ExtractFaceFeature(pImageEngine, srcImage, out singleFaceInfo); //清空上次的匹配结果 for (int i = 0; i < ImagesFeatureList.Count; i++) { //_imageList.Items[i].Text = string.Format("{0}号", i); } //获取缩放比例 float scaleRate = UtilTool.GetWidthAndHeight(srcImage.Width, srcImage.Height, (int)FRC.FIView._faceIdentificationImageBox.Width, (int)FRC.FIView._faceIdentificationImageBox.Height); //缩放图片 srcImage = UtilTool.ScaleImage(srcImage, (int)FRC.FIView._faceIdentificationImageBox.Width, (int)FRC.FIView._faceIdentificationImageBox.Height); //添加标记 srcImage = UtilTool.MarkRectAndString(srcImage, (int)(temp.left * scaleRate), (int)(temp.top * scaleRate), (int)(temp.right * scaleRate) - (int)(temp.left * scaleRate), (int)(temp.bottom * scaleRate) - (int)(temp.top * scaleRate), ageTemp, genderTemp, (int)FRC.FIView._faceIdentificationImageBox.Width); //显示标记后的图像 FRC.FIView._faceIdentificationImageBox.Source = UtilTool.BitmapToBitmapImage(srcImage); MatchImage(); }