public ASF_LivenessInfo GetLivenessScoreIR(Bitmap bitmap, ASF_SingleFaceInfo singleFaceInfo) { var retCode = MError.MERR_UNKNOWN; var livenessinfo = new ASF_LivenessInfo(); try { if (ptrVideoEngine == IntPtr.Zero) { retCode = InitialEngineForVideo(); } else { retCode = MError.MOK; } if (retCode == MError.MOK) { livenessinfo = FaceProcessHelper.LivenessEstimationIR(ptrVideoEngine, bitmap, singleFaceInfo); } if (retCode != MError.MOK) { Afw.Core.Helper.SimplifiedLogHelper.WriteIntoSystemLog(nameof(Afw.WinForm.EngineContext), $"GetLivenessScore Error:{retCode.GetFieldDescription()}"); } } catch (Exception ex) { Afw.Core.Helper.SimplifiedLogHelper.WriteIntoSystemLog(nameof(Afw.WinForm.EngineContext), $"GetLivenessScore Exception:{ex.ToString()}"); } return(livenessinfo); }
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 ASF_MultiFaceInfo DetectFaceIR(Image image) { var retCode = MError.MOK; if (ptrVideoEngine == IntPtr.Zero) { retCode = InitialEngineForVideo(); } if (retCode == MError.MOK) { return(FaceProcessHelper.DetectFaceIR(ptrVideoEngine, image)); } return(default(ASF_MultiFaceInfo)); }
public IntPtr ExtractFeature(Image image, ASF_SingleFaceInfo singleFaceInfo) { IntPtr ptrFeature = IntPtr.Zero; var retCode = MError.MOK; if (ptrVideoImageEngine == IntPtr.Zero) { retCode = InitialEngineForVideoImage(); } if (retCode == MError.MOK) { ptrFeature = FaceProcessHelper.ExtractFeature(ptrVideoImageEngine, image, singleFaceInfo); } return(ptrFeature); }
/// <summary> /// 为注册会员检测人脸 /// </summary> /// <param name="transImageInfo"></param> /// <returns></returns> public MError DeteceForMemberEnroll( out string errMsg, out IntPtr ptrImgFeature, out ASF_SingleFaceInfo singleFaceInfo, out int face3DStatus, out int faceNum, out string faceDesc, ref Image srcImage, int imageContainerWidth, int imageContainerHeight) { faceNum = 0; face3DStatus = -1; faceDesc = string.Empty; errMsg = string.Empty; ptrImgFeature = IntPtr.Zero; StringBuilder sbErrMsg = new StringBuilder(); var retCode = MError.MERR_UNKNOWN; int retAge = -1; int retGender = -1; int ret3DAngle = -1; singleFaceInfo = new ASF_SingleFaceInfo(); try { if (ptrImageEngine == IntPtr.Zero) { retCode = InitialEngineForImage(); } else { retCode = MError.MOK; } if (retCode == MError.MOK) { //调整图像宽度,需要宽度为4的倍数 if (srcImage.Width % 4 != 0) { //srcImage = ImageHelper.ScaleImage(srcImage, picImageCompare.Width, picImageCompare.Height); srcImage = ImageHelper.ScaleImage(srcImage, srcImage.Width - (srcImage.Width % 4), srcImage.Height); } //调整图片数据,非常重要 ImageInfo transImageInfo = ImageHelper.ReadBMP(srcImage); //人脸检测 ASF_MultiFaceInfo multiFaceInfo = FaceProcessHelper.DetectFace(ptrImageEngine, transImageInfo); faceNum = multiFaceInfo.faceNum; if (multiFaceInfo.faceNum != 1) { retCode = MError.MERR_ASF_EX_INVALID_FACE_INFO; sbErrMsg.Append(multiFaceInfo.faceNum > 1 ? "检测到多张人脸" : "未检测到人脸"); } else { ASF_AgeInfo ageInfo = FaceProcessHelper.AgeEstimation(ptrImageEngine, transImageInfo, multiFaceInfo, out retAge); ASF_GenderInfo genderInfo = FaceProcessHelper.GenderEstimation(ptrImageEngine, transImageInfo, multiFaceInfo, out retGender); ASF_Face3DAngle face3DAngleInfo = FaceProcessHelper.Face3DAngleDetection(ptrImageEngine, transImageInfo, multiFaceInfo, out ret3DAngle); #region 标记出检测到的人脸 MRECT temp = new MRECT(); int ageTemp = 0; int genderTemp = 0; int rectTemp = 0; //标记出检测到的人脸 for (int i = 0; i < multiFaceInfo.faceNum; i++) { MRECT rect = MemoryHelper.PtrToStructure <MRECT>(multiFaceInfo.faceRects + MemoryHelper.SizeOf <MRECT>() * i); int orient = MemoryHelper.PtrToStructure <int>(multiFaceInfo.faceOrients + MemoryHelper.SizeOf <int>() * i); int age = 0; if (retAge != 0) { sbErrMsg.AppendLine($"年龄检测失败,返回{retAge}!"); } else { age = MemoryHelper.PtrToStructure <int>(ageInfo.ageArray + MemoryHelper.SizeOf <int>() * i); } int gender = -1; if (retGender != 0) { sbErrMsg.AppendLine($"性别检测失败,返回{retGender}!"); } else { gender = MemoryHelper.PtrToStructure <int>(genderInfo.genderArray + MemoryHelper.SizeOf <int>() * i); } //int face3DStatus = -1; float roll = 0f; float pitch = 0f; float yaw = 0f; if (ret3DAngle != 0) { sbErrMsg.AppendLine($"3DAngle检测失败,返回{ret3DAngle}!"); } else { //角度状态 非0表示人脸不可信 face3DStatus = MemoryHelper.PtrToStructure <int>(face3DAngleInfo.status + MemoryHelper.SizeOf <int>() * i); //roll为侧倾角,pitch为俯仰角,yaw为偏航角 roll = MemoryHelper.PtrToStructure <float>(face3DAngleInfo.roll + MemoryHelper.SizeOf <float>() * i); pitch = MemoryHelper.PtrToStructure <float>(face3DAngleInfo.pitch + MemoryHelper.SizeOf <float>() * i); yaw = MemoryHelper.PtrToStructure <float>(face3DAngleInfo.yaw + MemoryHelper.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 = ImageHelper.MarkRectAndString(srcImage, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, age, gender); faceDesc = $"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")} - 人脸坐标:[left:{rect.left},top:{rect.top},right:{rect.right},bottom:{rect.bottom},orient:{orient},roll:{roll},pitch:{pitch},yaw:{yaw},status:{face3DStatus}] Age:{age} Gender:{(gender >= 0 ? gender.ToString() : "")}\n"; } //提取人脸特征 ptrImgFeature = FaceProcessHelper.ExtractFeature(ptrImageEngine, srcImage, out singleFaceInfo); float scaleRate = ImageHelper.GetWidthAndHeight(srcImage.Width, srcImage.Height, imageContainerWidth, imageContainerHeight); srcImage = ImageHelper.ScaleImage(srcImage, imageContainerWidth, imageContainerHeight); srcImage = ImageHelper.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, imageContainerWidth); #endregion } MemoryHelper.Free(transImageInfo.imgData); } errMsg = sbErrMsg.ToString(); } catch (Exception ex) { Afw.Core.Helper.SimplifiedLogHelper.WriteIntoSystemLog(nameof(Afw.WinForm.EngineContext), $"DeteceForMemberEnroll Exception:{ex.ToString()}"); } return(retCode); }
/// <summary> /// 图像显示到窗体上,得到每一帧图像,并进行处理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void videoSource_Paint(object sender, PaintEventArgs e) { if (videoSource.IsRunning) { //得到当前摄像头下的图片 Bitmap bitmap = videoSource.GetCurrentVideoFrame(); if (bitmap == null) { return; } Graphics g = e.Graphics; float offsetX = videoSource.Width * 1f / bitmap.Width; float offsetY = videoSource.Height * 1f / bitmap.Height; ASF_MultiFaceInfo multiFaceInfoIr = default(ASF_MultiFaceInfo); //检测人脸,得到Rect框 ASF_MultiFaceInfo multiFaceInfo = engineContext.DetectFace(bitmap); if (multiFaceInfo.Equals(default(ASF_MultiFaceInfo))) { return; } //得到最大人脸 ASF_SingleFaceInfo maxFace = FaceProcessHelper.GetMaxFace(multiFaceInfo); //得到Rect MRECT rect = maxFace.faceRect; 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(pen, x, y, width, height); if (trackUnit.message != "" && x > 0 && y > 0) { //将上一帧检测结果显示到页面上 g.DrawString(trackUnit.message, font, brush, x, y + 5); } //保证只检测一帧,防止页面卡顿以及出现其他内存被占用情况 if (isLock == false) { //g.DrawRectangle(pen, x, y, width, height); //if (trackUnit.message != "" && x > 0 && y > 0) //{ // //将上一帧检测结果显示到页面上 // g.DrawString(trackUnit.message, font, brush, x, y + 5); //} isLock = true; //异步处理提取特征值和比对,不然页面会比较卡 ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { if (rect.left != 0 && rect.right != 0 && rect.top != 0 && rect.bottom != 0) { try { var liveness = 1; var livenessIR = -1; if (this.chbLiveness.Checked) { liveness = -1; var livenessInfo = engineContext.GetLivenessScore(bitmap, maxFace); try { liveness = MemoryHelper.PtrToStructure <int>(livenessInfo.isLive); } catch (Exception ex) { liveness = -1; this.Invoke(new Action(delegate { //WinMessageHelper.SendMessage(this.Handle, UserMessage.WM_MESSAGE, IntPtr.Zero, $"liveness => {ex.Message}"); Afw.Core.Helper.SimplifiedLogHelper.WriteIntoSystemLog(nameof(FaceForm), $"videoSource_Paint livenessInfo exception=> {ex.ToString()}"); })); } } if (currentIrImage != null) { //检测人脸,得到Rect框 multiFaceInfoIr = engineContext.DetectFaceIR(currentIrImage); if (multiFaceInfoIr.faceNum > 0) { //得到最大人脸 ASF_SingleFaceInfo maxFaceIR = FaceProcessHelper.GetMaxFace(multiFaceInfoIr); var livenessInfoIR = engineContext.GetLivenessScoreIR(currentIrImage, maxFace); try { livenessIR = MemoryHelper.PtrToStructure <int>(livenessInfoIR.isLive); } catch (Exception ex) { livenessIR = -1; this.Invoke(new Action(delegate { //WinMessageHelper.SendMessage(this.Handle, UserMessage.WM_MESSAGE, IntPtr.Zero, $"liveness IR => {ex.Message}"); Afw.Core.Helper.SimplifiedLogHelper.WriteIntoSystemLog(nameof(FaceForm), $"videoSource_Paint livenessIRInfo exception=> {ex.ToString()}"); })); } } else { livenessIR = -1; } } else { livenessIR = engineContext.IrCameraIdx >= 0 ? -1 : 1; } if (liveness == 1 && livenessIR == 1) { //提取人脸特征 IntPtr feature = engineContext.ExtractFeature(bitmap, maxFace); float similarity = 0f; if (feature == IntPtr.Zero) { return; } //得到比对结果 int result = CompareFeature(feature, out similarity); if (result > -1) { //将比对结果放到显示消息中,用于最新显示 trackUnit.message = $" 员工Id{result} 相似度{similarity}"; this.Invoke(new Action(delegate { var member = iFaceDataRepository.GetById(result); WinMessageHelper.SendMessage(this.Handle, UserMessage.WM_MESSAGE, IntPtr.Zero, $"人脸比对成功,【姓名:{member.Name},雇员号:{member.EmployeeNo}】"); if (this.chbAutoCloseVideo.Checked) { ButtonEnableForImage(); btnStartVideo.Text = "开启摄像头"; engineContext.StopVideoCapture(); this.rdbThresholdHigh.Enabled = true; this.rdbThresholdLow.Enabled = true; this.rdbThresholdMid.Enabled = true; this.dgvFace.Enabled = true; MessageBox.Show($"人脸比对成功,【姓名:{member.Name},雇员号:{member.EmployeeNo}】"); } })); } else { //重置显示消息 trackUnit.message = ""; } MemoryHelper.Free(feature); } else { trackUnit.message = ""; } } catch (Exception ex) { this.Invoke(new Action(delegate { WinMessageHelper.SendMessage(this.Handle, UserMessage.WM_MESSAGE, IntPtr.Zero, ex.Message); })); } finally { isLock = false; } } isLock = false; if (currentIrImage != null) { currentIrImage = null; } })); } } GC.Collect(); }