Exemple #1
0
        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);
        }
Exemple #2
0
        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>());
        }
Exemple #3
0
        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));
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        /// <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);
        }
Exemple #6
0
        /// <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();
        }