Example #1
0
        /// <summary>
        /// 比对函数,将每一帧抓拍的照片和身份证照片进行比对
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private bool CompareImgWithIDImg(Bitmap bitmap, PaintEventArgs e)
        {
            recTimes--;
            if (bitmap == null)
            {
                return(false);
            }
            Graphics g       = e.Graphics;
            float    offsetX = videoSource.Width * 1f / bitmap.Width;
            float    offsetY = videoSource.Height * 1f / bitmap.Height;
            //检测人脸,得到Rect框
            ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pVideoEngine, bitmap);
            //得到最大人脸
            ASF_SingleFaceInfo maxFace = FaceUtil.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);
            //将上一帧检测结果显示到页面上
            g.DrawString(trackUnit.message, font, brush, x, y + 5);
            //保证只检测一帧,防止页面卡顿以及出现其他内存被占用情况
            if (isLock == false)
            {
                isLock = true;
                //异步处理提取特征值和比对,不然页面会比较卡
                ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                {
                    if (rect.left != 0 && rect.right != 0 && rect.top != 0 && rect.bottom != 0)
                    {
                        try
                        {
                            //提取人脸特征
                            IntPtr feature            = FaceUtil.ExtractFeature(pVideoImageEngine, bitmap, maxFace);
                            float similarity          = CompareTwoFeatures(feature, idCardHelper.idInfo.imageFeature);
                            this.similarity.Text      = ("相似度为: " + similarity.ToString("P"));; //显示在界面上
                            this.similarity.ForeColor = similarity > threshold ? Color.Green : Color.Red;
                            //得到比对结果
                            int result = (CompareTwoFeatures(feature, idCardHelper.idInfo.imageFeature) >= threshold) ? 1 : -1;
                            if (result > -1)
                            {
                                bool isLiveness     = false;
                                ImageInfo imageInfo = ImageUtil.ReadBMP(bitmap); //调整图片数据
                                if (imageInfo == null)
                                {
                                    return;
                                }
                                int retCode_Liveness = -1;
                                //RGB活体检测
                                ASF_LivenessInfo liveInfo = FaceUtil.LivenessInfo_RGB(pVideoImageEngine, imageInfo, multiFaceInfo, out retCode_Liveness);
                                //判断检测结果
                                if (retCode_Liveness == 0 && liveInfo.num > 0)
                                {
                                    int isLive = MemoryUtil.PtrToStructure <int>(liveInfo.isLive);
                                    isLiveness = (isLive == 1) ? true : false;
                                }
                                if (isLiveness)//活体检测成功
                                {
                                    //存放当前人脸识别的相似度
                                    idCardHelper.idInfo.similarity = similarity;
                                    //记录下当前的摄像头的人脸抓拍照
                                    idCardHelper.idInfo.capImage = bitmap;
                                    //验证通过则不再是当前身份证,等待下一次身份证
                                    idCardHelper.idInfo.isRight = false;
                                    //在子线程中输出信息到messageBox
                                    AppendText p = new AppendText(AddTextToMessBox);
                                    lbl_msg.Invoke(p, "人脸验证成功,请取卡...\n");
                                    pass = 1;
                                    idCardHelper.idInfo.isPass = 1;
                                    //将比对结果放到显示消息中,用于最新显示
                                    trackUnit.message = string.Format("通过验证,相似度为{0}", similarity);
                                    FileHelper.DeleteFile(m_strPath); //删除验证过的本地文件
                                    Thread.Sleep(1000);               //延时1秒
                                    this.IDPbox.Image = defaultImage; //照片恢复默认照片
                                    trackUnit.message = "";           //人脸识别框文字置空
                                    setFormResultValue(true);
                                }
                                else
                                {
                                    pass = 0;//标志未通过
                                    trackUnit.message = "未通过,系统识别为照片";
                                    AppendText p      = new AppendText(AddTextToMessBox);
                                    lbl_msg.Invoke(p, "抱歉,您未通过人脸验证...\n");
                                    FileHelper.DeleteFile(m_strPath);//删除验证过的本地文件
                                }
                            }
                            else
                            {
                                pass = 0;//标志未通过
                                trackUnit.message = "未通过人脸验证";
                                AppendText p      = new AppendText(AddTextToMessBox);
                                lbl_msg.Invoke(p, "抱歉,您未通过人脸验证...\n");
                                FileHelper.DeleteFile(m_strPath);//删除验证过的本地文件
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                            FileHelper.DeleteFile(m_strPath);//删除验证过的本地文件
                        }
                        finally
                        {
                            isLock = false;
                        }
                    }
                    isLock = false;
                }));
            }
            return(false);
        }
        //比对函数
        //将每一帧抓拍的照片和身份证照片进行比对
        private bool CompareImgWithIDImg(Bitmap bitmap, PaintEventArgs e)
        {
            recTimes--;

            if (bitmap == null)
            {
                return(false);
            }
            Graphics g       = e.Graphics;
            float    offsetX = videoSource.Width * 1f / bitmap.Width;
            float    offsetY = videoSource.Height * 1f / bitmap.Height;
            //检测人脸,得到Rect框
            ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pVideoEngine, bitmap);
            //得到最大人脸
            ASF_SingleFaceInfo maxFace = FaceUtil.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)
            {
                isLock = true;

                //异步处理提取特征值和比对,不然页面会比较卡
                ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                {
                    if (rect.left != 0 && rect.right != 0 && rect.top != 0 && rect.bottom != 0)
                    {
                        try
                        {
                            //提取人脸特征
                            IntPtr feature   = FaceUtil.ExtractFeature(pVideoImageEngine, bitmap, maxFace);
                            float similarity = CompareTwoFeatures(feature, idInfo.imageFeature);
                            messageBox.AppendText("相似度为: " + similarity);
                            this.similarityText.Text = similarity.ToString(); //显示在界面上

                            //得到比对结果
                            int result = (CompareTwoFeatures(feature, idInfo.imageFeature) >= threshold) ? 1 : -1;
                            if (result > -1)
                            {
                                //存放当前人脸识别的相似度
                                idInfo.similarity = similarity;

                                //记录下当前的摄像头的人脸抓拍照
                                idInfo.capImage = bitmap;

                                //标志人脸比对验证通过
                                faceState = true;

                                //验证通过则不再是当前身份证,等待下一次身份证
                                idInfo.isRight = false;

                                //在子线程中输出信息到messageBox
                                AppendText p = new AppendText(AddTextToMessBox);
                                messageBox.Invoke(p, "人脸验证成功,请通过闸机...\n");

                                //关闭读卡线程
                                //workThread.Suspend();

                                //最终通过闸机
                                pass = 1;

                                //以人脸识别的方式通过闸机
                                idInfo.isPass = 1;

                                /*
                                 *通信部分,将内存中的数据存放到数据库中
                                 */
                                //将身份证数据传入到服务器上
                                sendMessageToServer();


                                //将比对结果放到显示消息中,用于最新显示
                                trackUnit.message = string.Format("通过验证,相似度为{0}", similarity);
                                DeleteFile();   //删除验证过的本地文件


                                //延时3秒
                                Thread.Sleep(1000);

                                //照片恢复默认照片
                                this.IDPbox.Image = defaultImage;
                            }
                            else
                            {
                                pass = 0;
                                //重置显示消息
                                trackUnit.message = "未通过人脸验证";
                                AppendText p      = new AppendText(AddTextToMessBox);
                                messageBox.Invoke(p, "抱歉,您未通过人脸验证...\n");


                                DeleteFile();   //删除验证过的本地文件
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                            DeleteFile();   //删除验证过的本地文件
                        }
                        finally
                        {
                            isLock = false;
                        }
                    }
                    isLock = false;
                }));
            }
            return(false);
        }
Example #3
0
        /// <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();
            if (multiFaceInfo.faceRects == null)
            {
                ASF_FaceFeature emptyFeature  = new ASF_FaceFeature();
                IntPtr          pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>());
                MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature);
                return(pEmptyFeature);
            }
            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)
            {
                //释放指针
                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);

            byte[] feature = new byte[faceFeature.featureSize];
            MemoryUtil.Copy(faceFeature.feature, feature, 0, faceFeature.featureSize);

            ASF_FaceFeature localFeature = new ASF_FaceFeature();

            localFeature.feature = MemoryUtil.Malloc(feature.Length);
            MemoryUtil.Copy(feature, 0, localFeature.feature, feature.Length);
            localFeature.featureSize = feature.Length;
            IntPtr pLocalFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>());

            MemoryUtil.StructureToPtr(localFeature, pLocalFeature);

            //释放指针
            MemoryUtil.Free(pSingleFaceInfo);
            MemoryUtil.Free(pFaceFeature);

            return(pLocalFeature);
        }
Example #4
0
        private void InitDB()
        {
            string allselect = "selsect * from face";

            conn.Open();
            MySqlCommand    cmd  = new MySqlCommand(allselect, conn);
            MySqlDataReader read = cmd.ExecuteReader();

            if (read.FieldCount == 0)
            {
                return;
            }
            while (read.Read())
            {
                int    i        = 0;
                string _name    = read.GetString("name");
                string path     = read.GetString("face");
                Image  srcImage = Image.FromFile(path);
                if (srcImage == null)
                {
                    return;
                }
                srcImage = ImageUtil.ScaleImage(srcImage, picImageCompare.Width, picImageCompare.Height);
                ImageInfo          imageInfo      = ImageUtil.ReadBMP(srcImage);
                ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo();
                //提取人脸特征
                IntPtr ptr = FaceUtil.ExtractFeature(pEngine, srcImage, out singleFaceInfo);

                if (ptr == IntPtr.Zero)
                {
                    continue;
                }
                imagePathList.Add(path);
                imagesFeatureList.Add(ptr);
                KeyValuePair <string, IntPtr> pair = new KeyValuePair <string, IntPtr>(path, ptr);
                People people = new People(_name, pair);
                peoples.Add(people);
                //人脸检测与剪裁
                ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                {
                    ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pEngine, srcImage);

                    if (multiFaceInfo.faceNum > 0)
                    {
                        imagePathList.Add(path);
                        MRECT rect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects);
                        srcImage   = ImageUtil.CutImage(srcImage, rect.left, rect.top, rect.right, rect.bottom);
                    }


                    this.Invoke(new Action(delegate
                    {
                        if (srcImage == null)
                        {
                            srcImage = Image.FromFile(path);
                        }
                        imageLists.Images.Add(path, srcImage);
                        imageList.Items.Add(i + "号", path);
                        i++;
                        srcImage = null;
                    }));
                }));
            }
        }
Example #5
0
        private void Form_User_Load(object sender, EventArgs e)
        {
            //必须保证有可用摄像头
            if (filterInfoCollection.Count == 0)
            {
                MessageBox.Show("未检测到摄像头,请确保已安装摄像头或驱动!");
                Dispose();
                Application.Exit();
            }
            if (videoSource.IsRunning)
            {
                videoSource.SignalToStop();
                videoSource.Hide();
            }
            else
            {
                if (isCompare)
                {
                    //比对结果清除
                    for (int i = 0; i < imagesFeatureList.Count; i++)
                    {
                        imageList.Items[i].Text = string.Format("{0}号", i);
                    }
                    isCompare = false;
                }
                videoSource.Show();
                deviceVideo = new VideoCaptureDevice(filterInfoCollection[0].MonikerString);
                deviceVideo.VideoResolution = deviceVideo.VideoCapabilities[0];
                videoSource.VideoSource     = deviceVideo;
                videoSource.Start();
            }
            lock (locker)
            {
                List <string> imagePathListTemp = new List <string>();
                var           numStart          = imagePathList.Count;
                //查询数据库
                DataMysql datasql = new DataMysql();
                datasql.dataCon();
                string  cmdStr = "Select faceimg from user";
                DataSet ds;
                ds = datasql.getDataSet(cmdStr);
                int j = 0;
                j = ds.Tables[0].Rows.Count;
                string[] fileNames = new string[j];
                j = 0;
                foreach (DataRow Row in ds.Tables[0].Rows)
                {
                    fileNames[j] = Convert.ToString(Row["faceimg"]);
                    j++;
                }

                for (int i = 0; i < fileNames.Length; i++)
                {
                    imagePathListTemp.Add(fileNames[i]);
                }

                //人脸检测以及提取人脸特征
                ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                {
                    //人脸检测和剪裁
                    for (int i = 0; i < imagePathListTemp.Count; i++)
                    {
                        WebRequest request   = WebRequest.Create(imagePathListTemp[i]);
                        WebResponse response = request.GetResponse();
                        Stream s             = response.GetResponseStream();
                        byte[] data          = new byte[1024];
                        int length           = 0;
                        MemoryStream ms      = new MemoryStream();
                        while ((length = s.Read(data, 0, data.Length)) > 0)
                        {
                            ms.Write(data, 0, length);
                        }
                        ms.Seek(0, SeekOrigin.Begin);
                        //    pictureBox1.Image = Image.FromStream(ms);
                        Image image = Image.FromStream(ms);
                        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)
                        {
                            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;
                        }
                    }


                    //提取人脸特征
                    for (int i = numStart; i < imagePathList.Count; i++)
                    {
                        WebRequest request   = WebRequest.Create(imagePathListTemp[i]);
                        WebResponse response = request.GetResponse();
                        Stream s             = response.GetResponseStream();
                        byte[] data          = new byte[1024];
                        int length           = 0;
                        MemoryStream ms      = new MemoryStream();
                        while ((length = s.Read(data, 0, data.Length)) > 0)
                        {
                            ms.Write(data, 0, length);
                        }
                        ms.Seek(0, SeekOrigin.Begin);
                        ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo();
                        IntPtr feature = FaceUtil.ExtractFeature(pImageEngine, Image.FromStream(ms), 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);
                            }
                        }));
                    }
                }));
            }
            LoadingHelper.ShowLoading("加载中请稍后。", this, o =>
            {
                //这里写处理耗时的代码,代码处理完成则自动关闭该窗口
                Thread.Sleep(4000);
            });
        }
        /// <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;
                imageList.Refresh();
                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++)
                    {
                        //图片格式判断
                        if (checkImage(fileNames[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;
                            btnStartVideo.Enabled     = false;
                        }));

                        //人脸检测和剪裁
                        for (int i = 0; i < imagePathListTemp.Count; i++)
                        {
                            Image image = ImageUtil.readFromFile(imagePathListTemp[i]);
                            if (image == null)
                            {
                                continue;
                            }
                            if (image.Width > 1536 || image.Height > 1536)
                            {
                                image = ImageUtil.ScaleImage(image, 1536, 1536);
                            }
                            if (image == null)
                            {
                                continue;
                            }
                            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)
                            {
                                imagePathList.Add(imagePathListTemp[i]);
                                MRECT rect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects);
                                image      = ImageUtil.CutImage(image, rect.left, rect.top, rect.right, rect.bottom);
                            }
                            else
                            {
                                if (image != null)
                                {
                                    image.Dispose();
                                }
                                continue;
                            }
                            //显示人脸
                            this.Invoke(new Action(delegate
                            {
                                if (image == null)
                                {
                                    image = ImageUtil.readFromFile(imagePathListTemp[i]);

                                    if (image.Width > 1536 || image.Height > 1536)
                                    {
                                        image = ImageUtil.ScaleImage(image, 1536, 1536);
                                    }
                                }
                                imageLists.Images.Add(imagePathListTemp[i], image);
                                imageList.Items.Add((numStart + isGoodImage) + "号", imagePathListTemp[i]);
                                imageList.Refresh();
                                isGoodImage += 1;
                                if (image != null)
                                {
                                    image.Dispose();
                                }
                            }));
                        }

                        //提取人脸特征
                        for (int i = numStart; i < imagePathList.Count; i++)
                        {
                            ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo();
                            Image image = ImageUtil.readFromFile(imagePathList[i]);
                            if (image == null)
                            {
                                continue;
                            }
                            IntPtr feature = FaceUtil.ExtractFeature(pImageEngine, image, 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);
                                }
                            }));
                            if (image != null)
                            {
                                image.Dispose();
                            }
                        }
                        //允许点击按钮
                        Invoke(new Action(delegate
                        {
                            chooseMultiImgBtn.Enabled = true;
                            btnClearFaceList.Enabled  = true;
                            btnStartVideo.Enabled     = true;

                            if (btnStartVideo.Text == "启用摄像头")
                            {
                                chooseImgBtn.Enabled = true;
                                matchBtn.Enabled     = true;
                            }
                            else
                            {
                                chooseImgBtn.Enabled = false;
                                matchBtn.Enabled     = false;
                            }
                        }));
                    }));
                }
            }
        }
        /// <summary>
        /// RGB摄像头Paint事件,同步RGB人脸框,对比人脸框后进行IR活体检测
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void irVideoSource_Paint(object sender, PaintEventArgs e)
        {
            if (isDoubleShot && irVideoSource.IsRunning)
            {
                //如果双摄,且IR摄像头工作,获取IR摄像头图片
                Bitmap irBitmap = irVideoSource.GetCurrentVideoFrame();
                if (irBitmap == null)
                {
                    return;
                }
                //得到Rect
                MRECT rect = new MRECT();
                lock (rectLock)
                {
                    rect = allRect;
                }
                float irOffsetX = irVideoSource.Width * 1f / irBitmap.Width;
                float irOffsetY = irVideoSource.Height * 1f / irBitmap.Height;
                float offsetX   = irVideoSource.Width * 1f / rgbVideoSource.Width;
                float offsetY   = irVideoSource.Height * 1f / 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 = FaceUtil.DetectFace(pVideoIRImageEngine, irBitmap);
                                    if (irMultiFaceInfo.faceNum <= 0)
                                    {
                                        return;
                                    }
                                    //得到最大人脸
                                    ASF_SingleFaceInfo irMaxFace = FaceUtil.GetMaxFace(irMultiFaceInfo);
                                    //得到Rect
                                    MRECT irRect = irMaxFace.faceRect;
                                    //判断RGB图片检测的人脸框与IR摄像头检测的人脸框偏移量是否在误差允许范围内
                                    if (isInAllowErrorRange(rect.left * offsetX / irOffsetX, irRect.left) && isInAllowErrorRange(rect.right * offsetX / irOffsetX, irRect.right) &&
                                        isInAllowErrorRange(rect.top * offsetY / irOffsetY, irRect.top) && isInAllowErrorRange(rect.bottom * offsetY / irOffsetY, irRect.bottom))
                                    {
                                        int retCode_Liveness = -1;
                                        //将图片进行灰度转换,然后获取图片数据
                                        ImageInfo irImageInfo = ImageUtil.ReadBMP_IR(irBitmap);
                                        if (irImageInfo == null)
                                        {
                                            return;
                                        }
                                        //IR活体检测
                                        ASF_LivenessInfo liveInfo = FaceUtil.LivenessInfo_IR(pVideoIRImageEngine, irImageInfo, irMultiFaceInfo, out retCode_Liveness);
                                        //判断检测结果
                                        if (retCode_Liveness == 0 && liveInfo.num > 0)
                                        {
                                            int isLive = MemoryUtil.PtrToStructure <int>(liveInfo.isLive);
                                            isLiveness = (isLive == 1) ? true : false;
                                        }
                                        if (irImageInfo != null)
                                        {
                                            MemoryUtil.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;
                    }));
                }
            }
        }
Example #8
0
        /// <summary>
        /// 导入照片录入
        /// </summary>
        /// <param name="IsOfflineRecord">是否为本地导入</param>
        public void ImportImgesFun(bool IsOfflineRecord)
        {
            lock (locker)
            {
                List <string> imagePathListTemp = ImportImages(IsOfflineRecord);
                if (imagePathListTemp.Count <= 0)
                {
                    return;
                }
                FRC.PIVM.NaturalSourceImage = imagePathListTemp[0];

                var numStart    = ImagePathList.Count;
                int isGoodImage = 0;

                //人脸检测以及提取人脸特征
                ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                {
                    //人脸检测和剪裁
                    for (int i = 0; i < imagePathListTemp.Count; i++)
                    {
                        Image image = UtilTool.ReadImageFromFile(imagePathListTemp[i]);
                        if (image == null)
                        {
                            continue;
                        }
                        if (image.Width > 1536 || image.Height > 1536)
                        {
                            image = UtilTool.ScaleImage(image, 1536, 1536);
                        }
                        if (image == null)
                        {
                            continue;
                        }
                        if (image.Width % 4 != 0)
                        {
                            image = UtilTool.ScaleImage(image, image.Width - (image.Width % 4), image.Height);
                        }
                        //人脸检测
                        ASF_MultiFaceInfo multiFaceInfo = UtilToolFace.DetectFace(pImageEngine, image);
                        //判断检测结果
                        if (multiFaceInfo.faceNum > 0)
                        {
                            ImagePathList.Add(imagePathListTemp[i]);
                            MRECT rect = UtilToolMemory.PtrToStructure <MRECT>(multiFaceInfo.faceRects);
                            image      = UtilTool.CutImage(image, rect.left, rect.top, rect.right, rect.bottom);
                        }
                        else
                        {
                            if (image != null)
                            {
                                image.Dispose();
                            }
                            continue;
                        }
                        //显示人脸
                        FRC.MainView.Dispatcher.Invoke(new Action(delegate
                        {
                            if (image == null)
                            {
                                image = UtilTool.ReadImageFromFile(imagePathListTemp[i]);

                                if (image.Width > 1536 || image.Height > 1536)
                                {
                                    image = UtilTool.ScaleImage(image, 1536, 1536);
                                }
                            }
                            //_imageLists.Images.Add(imagePathListTemp[i], image);
                            //_imageList.Items.Add((numStart + isGoodImage) + "号", imagePathListTemp[i]);
                            isGoodImage += 1;
                            if (image != null)
                            {
                                image.Dispose();
                            }
                        }));
                    }

                    //提取人脸特征
                    for (int i = numStart; i < ImagePathList.Count; i++)
                    {
                        ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo();
                        Image image = UtilTool.ReadImageFromFile(ImagePathList[i]);
                        if (image == null)
                        {
                            continue;
                        }
                        IntPtr feature = UtilToolFace.ExtractFaceFeature(pImageEngine, image, out singleFaceInfo);

                        FRC.PIVM.FaceCharacteristics = feature;

                        FRC.MainView.Dispatcher.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);
                            }
                        }));
                        if (image != null)
                        {
                            image.Dispose();
                        }
                    }
                    FRC.MainView.Dispatcher.Invoke(new Action(delegate
                    {
                        FRC.MainVM.IsCameraEnable = true;

                        //FRC.MainVM.IsPGBtnEnable = true;
                        FRC.MainVM.IsSIBtnEnable = true;
                        //FRC.MainVM.IsPGIBtnEnable = true;
                        FRC.MainVM.IsSIIBtnEnable = true;
                    }));
                }));

                //保存个人信息数据
                //FRC.UploadFaceRecord();
            }
        }
Example #9
0
        /// <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();
        }
Example #10
0
        private bool getFaceFeature(ref t_face t_Face)
        {
            Image image  = ImageUtil.readFromFile(t_Face.image_path);
            bool  result = false;

            //压缩图片的长宽为临界大小1536
            if (image.Width > 1536 || image.Height > 1536)
            {
                image = ImageUtil.ScaleImage(image, 1536, 1536);
            }

            //裁剪,因为虹软要求图片宽度要是4的整数倍,所以要检测一下,如果不是就把宽缩小为4的倍数
            if (image.Width % 4 != 0)
            {
                image = ImageUtil.ScaleImage(image, image.Width - (image.Width % 4), image.Height);
            }

            //把image对象转化为位图的对象
            Bitmap bitmap = new Bitmap(image);

            //使用人脸检测引擎去检测人脸,返回的lis列表里存了人脸的位置
            List <FaceInfo> faceInfos = faceImageRecognizer.ScanFaces(bitmap);

            //判断一张照片是否就一个人脸
            if (faceInfos.Count == 1)
            {
                //把第一个人脸的信息传入人脸识别引擎中,提取出特征的结构体指引到faceinfo中,返回是否成功
                int num = faceImageRecognizer.ScanFaceFeature(bitmap, faceInfos[0]);

                if (num == 0)
                {
                    ASF_SingleFaceInfo singleFaceInfo = faceInfos[0].singleFaceInfo;
                    //t_face就是实体类映射对象
                    t_Face.face_feature_length = faceInfos[0].faceFeature.featureSize;
                    t_Face.face_feature        = new byte[(int)t_Face.face_feature_length];

                    //把结构体里的特征纯copy到t_face中
                    MemoryUtil.Copy(faceInfos[0].faceFeature.feature, t_Face.face_feature, 0, faceInfos[0].faceFeature.featureSize);
                    result = true;
                    LoggerService.logger.Info(string.Format("已提取人脸特征值,[left:{0},right:{1},top:{2},bottom:{3},orient:{4}]", singleFaceInfo.faceRect.left, singleFaceInfo.faceRect.right, singleFaceInfo.faceRect.top, singleFaceInfo.faceRect.bottom, singleFaceInfo.faceOrient));
                    string tempImagePath = t_Face.image_path;
                    string id            = t_Face.studnet_id;

                    //裁剪出头像,依次展示在界面,多线程操作,解决可能异常越界问题
                    Invoke(new Action(() => {
                        image = ImageUtil.CutImage(image, singleFaceInfo.faceRect.left, singleFaceInfo.faceRect.top, singleFaceInfo.faceRect.right, singleFaceInfo.faceRect.bottom);
                        imageLists.Images.Add(tempImagePath, image);
                        ImageListView.Items.Add(id, tempImagePath);

                        listViewFaceDetal.Items.Add(new ListViewItem(new string[] { "等待", id, "" }));
                        listViewFaceDetal.Refresh();
                        ImageListView.Refresh();
                    }));
                }
                else
                {
                    LoggerService.logger.Error("提取人脸特征失败!");
                }
                faceInfos[0].Dispose();
                faceInfos[0] = null;
                faceInfos.Clear();
            }

            image.Dispose();
            bitmap.Dispose();

            return(result);
        }
Example #11
0
        /// <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);// 返回人脸特征
        }
 public static extern MResult ASFFaceFeatureExtractEx(IntPtr hEngine, ASVLOFFSCREEN imgData, ASF_SingleFaceInfo faceInfo, out ASF_FaceFeature feature, int threadNum = 1);
 public static extern MResult ASFFaceFeatureExtract(IntPtr hEngine, int width, int height, int format, IntPtr imgData, ASF_SingleFaceInfo faceInfo, out ASF_FaceFeature feature, int threadNum = 1);
Example #14
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();
        }
Example #15
0
        private void btnSelectImageToRegister_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Title  = "Select";
            openFileDialog.Filter = "Image File|*.bmp;*.jpg;*.jpeg;*.png";
            //openFileDialog.Multiselect = true;
            openFileDialog.FileName = string.Empty;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                var    numStart = imagePathList.Count;
                string fileName = openFileDialog.FileName;
                if (!checkImage(fileName))
                {
                    return;
                }

                pictureBoxSelected.ImageLocation = fileName;
                currentLeftFeature = IntPtr.Zero;

                //人脸检测以及提取人脸特征
                ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                {
                    Image image = ImageUtil.readFromFile(fileName);
                    if (image == null)
                    {
                        return;
                    }
                    if (image.Width > 1536 || image.Height > 1536)
                    {
                        image = ImageUtil.ScaleImage(image, 1536, 1536);
                    }
                    if (image == null)
                    {
                        return;
                    }
                    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);
                    }
                    else
                    {
                        if (image != null)
                        {
                            image.Dispose();
                        }
                        return;
                    }

                    //提取人脸特征
                    ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo();
                    Image image1 = ImageUtil.readFromFile(fileName);
                    if (image1 == null)
                    {
                        return;
                    }
                    currentLeftFeature = FaceUtil.ExtractFeature(pImageEngine, image1, out singleFaceInfo);
                    this.Invoke(new Action(delegate
                    {
                        if (singleFaceInfo.faceRect.left == 0 && singleFaceInfo.faceRect.right == 0)
                        {
                            AppendText(string.Format("No face detected\r\r\n"));
                        }
                        else
                        {
                            AppendText(string.Format("Face landmark detected,[left:{0},right:{1},top:{2},bottom:{3},orient:{4}]\r\r\n", singleFaceInfo.faceRect.left, singleFaceInfo.faceRect.right, singleFaceInfo.faceRect.top, singleFaceInfo.faceRect.bottom, singleFaceInfo.faceOrient));
                            imagesFeatureList.Add(currentLeftFeature);
                        }
                    }));
                    if (image1 != null)
                    {
                        image1.Dispose();
                    }
                }));
            }
        }
Example #16
0
 public static extern MResult ASFImageQualityDetect(IntPtr hEngine, int width, int height, int format, IntPtr imgData, ASF_SingleFaceInfo faceInfo, int isMask, out float confidenceLevel, ASF_DetectModel detectModel = ASF_DetectModel.ASF_DETECT_MODEL_RGB);
Example #17
0
        private void btnSelectImageToRecognize_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();

            openFileDialog.Title  = "Select";
            openFileDialog.Filter = "Image File|*.bmp;*.jpg;*.jpeg;*.png";
            //openFileDialog.Multiselect = true;
            openFileDialog.FileName = string.Empty;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                var    numStart = imagePathList.Count;
                string fileName = openFileDialog.FileName;
                if (!checkImage(fileName))
                {
                    return;
                }

                image1Feature = IntPtr.Zero;
                pictureBoxToRecognize.ImageLocation = fileName;
                Image srcImage = ImageUtil.readFromFile(fileName);

                ASF_SingleFaceInfo singleFaceInfo = new ASF_SingleFaceInfo();
                //提取人脸特征
                image1Feature = FaceUtil.ExtractFeature(pImageEngine, srcImage, out singleFaceInfo);

                if (imagesFeatureList.Count == 0)
                {
                    MessageBox.Show("请注册人脸!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                if (image1Feature == IntPtr.Zero)
                {
                    if (pictureBoxToRecognize.Image == null)
                    {
                        MessageBox.Show("请选择识别图!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        MessageBox.Show("比对失败,识别图未提取到特征值!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    return;
                }

                for (int i = 0; i < imagesFeatureDictionary.Count; i++)
                {
                    IntPtr feature    = imagesFeatureDictionary.ElementAt(i).Key;
                    float  similarity = 0f;
                    int    ret        = ASFFunctions.ASFFaceFeatureCompare(pImageEngine, image1Feature, feature, ref similarity);
                    //增加异常值处理
                    if (similarity.ToString().IndexOf("E") > -1)
                    {
                        similarity = 0f;
                    }

                    if (similarity > threshold)
                    {
                        string name = imagesFeatureDictionary.ElementAt(i).Value;
                        AppendText("对比结果:" + name + "  可信度:" + similarity + "\r\n");
                        return;
                    }
                }
                AppendText("无结果\r\n");
            }
        }
Example #18
0
 public static extern MResult ASFImageQualityDetectEx(IntPtr hEngine, ASVLOFFSCREEN imgData, ASF_SingleFaceInfo faceInfo, int isMask, out float confidenceLevel, ASF_DetectModel detectModel = ASF_DetectModel.ASF_DETECT_MODEL_RGB);
        /// <summary>
        /// RGB摄像头Paint事件,图像显示到窗体上,得到每一帧图像,并进行处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void videoSource_Paint(object sender, PaintEventArgs e)
        {
            if (rgbVideoSource.IsRunning)
            {
                //得到当前RGB摄像头下的图片
                Bitmap bitmap = rgbVideoSource.GetCurrentVideoFrame();
                if (bitmap == null)
                {
                    return;
                }
                //检测人脸,得到Rect框
                ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pVideoEngine, bitmap);
                //得到最大人脸
                ASF_SingleFaceInfo maxFace = FaceUtil.GetMaxFace(multiFaceInfo);
                //得到Rect
                MRECT rect = maxFace.faceRect;
                //检测RGB摄像头下最大人脸
                Graphics g       = e.Graphics;
                float    offsetX = rgbVideoSource.Width * 1f / bitmap.Width;
                float    offsetY = 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 = ImageUtil.ReadBMP(bitmap);
                                if (imageInfo == null)
                                {
                                    return;
                                }
                                int retCode_Liveness = -1;
                                //RGB活体检测
                                ASF_LivenessInfo liveInfo = FaceUtil.LivenessInfo_RGB(pVideoRGBImageEngine, imageInfo, multiFaceInfo, out retCode_Liveness);
                                //判断检测结果
                                if (retCode_Liveness == 0 && liveInfo.num > 0)
                                {
                                    int isLive = MemoryUtil.PtrToStructure <int>(liveInfo.isLive);
                                    isLiveness = (isLive == 1) ? true : false;
                                }
                                if (imageInfo != null)
                                {
                                    MemoryUtil.Free(imageInfo.imgData);
                                }
                                if (isLiveness)
                                {
                                    //提取人脸特征
                                    IntPtr feature   = FaceUtil.ExtractFeature(pVideoRGBImageEngine, bitmap, maxFace);
                                    float similarity = 0f;
                                    //得到比对结果
                                    int result = compareFeature(feature, out similarity);
                                    MemoryUtil.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;
                    }));
                }
            }
        }
Example #20
0
 public static extern MResult ASFFaceFeatureExtract(IntPtr hEngine, int width, int height, int format, IntPtr imgData, ASF_SingleFaceInfo faceInfo, ASF_RegisterOrNot registerOrNot, int mask, out ASF_FaceFeature feature);
Example #21
0
        /// <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 srcImage = Image.FromFile(imagePathListTemp[i]);
                            ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pEngine, srcImage);

                            if (multiFaceInfo.faceNum > 0)
                            {
                                imagePathList.Add(imagePathListTemp[i]);

                                MRECT rect = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects);
                                srcImage   = ImageUtil.CutImage(srcImage, rect.left, rect.top, rect.right, rect.bottom);
                            }
                            else
                            {
                                continue;
                            }

                            this.Invoke(new Action(delegate
                            {
                                if (srcImage == null)
                                {
                                    srcImage = Image.FromFile(imagePathListTemp[i]);
                                }
                                imageLists.Images.Add(imagePathListTemp[i], srcImage);
                                imageList.Items.Add((numStart + isGoodImage) + "号", imagePathListTemp[i]);
                                isGoodImage += 1;
                                srcImage     = 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);
                                    KeyValuePair <string, IntPtr> pair = new KeyValuePair <string, IntPtr>(imagePathList[i], feature);
                                    string _name = string.Format("{0}号", i);
                                    if (textBox1.Text != null)
                                    {
                                        _name         = textBox1.Text;
                                        textBox1.Text = null;
                                    }
                                    People people = new People(_name, pair);
                                    peoples.Add(people);
                                    string sqlstr    = string.Format("insert into face(name,face) values('{0}','{1}')", _name, imagePathList[i]);
                                    MySqlCommand cmd = new MySqlCommand(sqlstr, conn);
                                    int resule       = cmd.ExecuteNonQuery();
                                }
                            }));
                        }
                        //imagePathList.AddRange(imagePathListTemp);
                        //允许点击按钮
                        Invoke(new Action(delegate
                        {
                            chooseMultiImgBtn.Enabled = true;
                            matchBtn.Enabled          = true;
                            btnClearFaceList.Enabled  = true;
                            chooseImgBtn.Enabled      = true;
                        }));
                    }));
                }
            }
        }
Example #22
0
 public static extern MResult ASFFaceFeatureExtractEx(IntPtr hEngine, ASVLOFFSCREEN imgData, ASF_SingleFaceInfo faceInfo, ASF_RegisterOrNot registerOrNot, int mask, out ASF_FaceFeature feature);
Example #23
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;
         //检测人脸,得到Rect框
         ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pVideoEngine, bitmap);
         //得到最大人脸
         ASF_SingleFaceInfo maxFace = FaceUtil.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)
         {
             isLock = true;
             //异步处理提取特征值和比对,不然页面会比较卡
             ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
             {
                 if (rect.left != 0 && rect.right != 0 && rect.top != 0 && rect.bottom != 0)
                 {
                     try
                     {
                         //提取人脸特征
                         IntPtr feature   = FaceUtil.ExtractFeature(pVideoImageEngine, bitmap, maxFace);
                         float similarity = 0f;
                         //得到比对结果
                         int result = compareFeature(feature, out similarity);
                         if (result > -1)
                         {
                             //将比对结果放到显示消息中,用于最新显示
                             trackUnit.message = string.Format("{0}号 {1}", result, similarity);
                             //执行数据库操作
                             SignSql(result);
                         }
                         else
                         {
                             //重置显示消息
                             trackUnit.message = "";
                         }
                     }
                     catch (Exception ex)
                     {
                         Console.WriteLine(ex.Message);
                     }
                     finally
                     {
                         isLock = false;
                     }
                 }
                 isLock = false;
             }));
         }
     }
 }
Example #24
0
        /// <summary>
        /// 提取单人脸特征
        /// </summary>
        /// <param name="pEngine">人脸识别引擎</param>
        /// <param name="image">图片</param>
        /// <param name="singleFaceInfo">单人脸信息</param>
        /// <returns>单人脸特征</returns>
        public static IntPtr ExtractFeature(IntPtr pEngine, Image image, ASF_SingleFaceInfo singleFaceInfo)
        {
            ImageInfo imageInfo = ImageUtil.ReadBMP(image);

            if (imageInfo == null)
            {
                ASF_FaceFeature emptyFeature  = new ASF_FaceFeature();
                IntPtr          pEmptyFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>());
                MemoryUtil.StructureToPtr(emptyFeature, pEmptyFeature);
                return(pEmptyFeature);
            }
            IntPtr pSingleFaceInfo = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_SingleFaceInfo>());

            MemoryUtil.StructureToPtr(singleFaceInfo, pSingleFaceInfo);

            IntPtr pFaceFeature = MemoryUtil.Malloc(MemoryUtil.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)
            {
                //释放指针
                MemoryUtil.Free(pSingleFaceInfo);
                MemoryUtil.Free(pFaceFeature);
                MemoryUtil.Free(imageInfo.imgData);

                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);

            byte[] feature = new byte[faceFeature.featureSize];
            MemoryUtil.Copy(faceFeature.feature, feature, 0, faceFeature.featureSize);

            ASF_FaceFeature localFeature = new ASF_FaceFeature();

            localFeature.feature = MemoryUtil.Malloc(feature.Length);
            MemoryUtil.Copy(feature, 0, localFeature.feature, feature.Length);
            localFeature.featureSize = feature.Length;
            IntPtr pLocalFeature = MemoryUtil.Malloc(MemoryUtil.SizeOf <ASF_FaceFeature>());

            MemoryUtil.StructureToPtr(localFeature, pLocalFeature);

            //释放指针
            MemoryUtil.Free(pSingleFaceInfo);
            MemoryUtil.Free(pFaceFeature);
            MemoryUtil.Free(imageInfo.imgData);

            return(pLocalFeature);
        }
Example #25
0
        /// <summary>
        /// “选择识别图片”按钮事件
        /// </summary>
        private void ChooseImg(object sender, EventArgs e)
        {
            lblCompareInfo.Text = "";
            if (pImageEngine == 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的倍数
                if (srcImage.Width % 4 != 0)
                {
                    //srcImage = ImageUtil.ScaleImage(srcImage, picImageCompare.Width, picImageCompare.Height);
                    srcImage = ImageUtil.ScaleImage(srcImage, srcImage.Width - (srcImage.Width % 4), srcImage.Height);
                }
                //调整图片数据,非常重要
                ImageInfo imageInfo = ImageUtil.ReadBMP(srcImage);
                //人脸检测
                ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pImageEngine, imageInfo);
                //年龄检测
                int         retCode_Age = -1;
                ASF_AgeInfo ageInfo     = FaceUtil.AgeEstimation(pImageEngine, imageInfo, multiFaceInfo, out retCode_Age);
                //性别检测
                int            retCode_Gender = -1;
                ASF_GenderInfo genderInfo     = FaceUtil.GenderEstimation(pImageEngine, imageInfo, multiFaceInfo, out retCode_Gender);

                //3DAngle检测
                int             retCode_3DAngle = -1;
                ASF_Face3DAngle face3DAngleInfo = FaceUtil.Face3DAngleDetection(pImageEngine, imageInfo, multiFaceInfo, out retCode_3DAngle);

                MemoryUtil.Free(imageInfo.imgData);

                if (multiFaceInfo.faceNum < 1)
                {
                    srcImage              = ImageUtil.ScaleImage(srcImage, picImageCompare.Width, picImageCompare.Height);
                    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));
                }


                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();// 单人脸检测
                //提取人脸特征
                image1Feature = FaceUtil.ExtractFeature(pImageEngine, srcImage, out singleFaceInfo);

                //清空上次的匹配结果
                for (int i = 0; i < imagesFeatureList.Count; i++)
                {
                    imageList.Items[i].Text = string.Format("{0}号", i);
                }

                float scaleRate = ImageUtil.getWidthAndHeight(srcImage.Width, srcImage.Height, picImageCompare.Width, picImageCompare.Height);
                srcImage = ImageUtil.ScaleImage(srcImage, picImageCompare.Width, picImageCompare.Height);
                srcImage = ImageUtil.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, picImageCompare.Width);


                //显示标记后的图像
                picImageCompare.Image = srcImage;
            }
        }
Example #26
0
        /// <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;

                    //保存图片路径并显示
                    // TODO 这边将从数据库获取人脸地址
                    string[] fileNames = openFileDialog.FileNames;
                    Console.WriteLine(fileNames.ToString());
                    for (int i = 0; i < fileNames.Length; i++)
                    {
                        imagePathListTemp.Add(fileNames[i]);// 将数据库查处的地址列表存入temp
                    }



                    //人脸检测以及提取人脸特征
                    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                    {
                        //禁止点击按钮
                        Invoke(new Action(delegate
                        {
                            chooseMultiImgBtn.Enabled = false;
                            matchBtn.Enabled          = false;
                            btnClearFaceList.Enabled  = false;
                            chooseImgBtn.Enabled      = false;
                            btnStartVideo.Enabled     = false;
                        }));

                        //人脸检测和剪裁
                        for (int i = 0; i < imagePathListTemp.Count; i++)
                        {
                            Image image = Image.FromFile(imagePathListTemp[i]);
                            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)
                            {
                                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();
                            // TODO  将feature存入数据库,byte[],这边已经在FaceUtils中处理了
                            IntPtr feature = FaceUtil.ExtractFeature(pImageEngine, 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);

                                    // TODO 数据库中查询出feature

                                    /*
                                     * IntPtr pFeatureItemFromDB;
                                     * MysqlUtils mysqlUtils = new MysqlUtils();
                                     * List<byte[]> featureListFromDB = mysqlUtils.SelectUserFaceByFeature();
                                     * foreach (byte[] featureItemFromDB in featureListFromDB)
                                     * {
                                     *  pFeatureItemFromDB = TabConvert.BytesToIntptr(featureItemFromDB);
                                     *  imagesFeatureList.Add(pFeatureItemFromDB);
                                     * }
                                     */
                                }
                            }));
                        }
                        //允许点击按钮
                        Invoke(new Action(delegate
                        {
                            chooseMultiImgBtn.Enabled = true;
                            btnClearFaceList.Enabled  = true;
                            btnStartVideo.Enabled     = true;

                            if (btnStartVideo.Text == "启用摄像头")
                            {
                                chooseImgBtn.Enabled = true;
                                matchBtn.Enabled     = true;
                            }
                            else
                            {
                                chooseImgBtn.Enabled = false;
                                matchBtn.Enabled     = false;
                            }
                        }));
                    }));
                }
            }
        }