/// <summary>
        /// 提取人脸特征
        /// </summary>
        /// <param name="pEngine">引擎Handle</param>
        /// <param name="image">图像</param>
        /// <returns>保存人脸特征结构体指针</returns>
        public static IntPtr ExtractFaceFeature(IntPtr pEngine, Image image, out ASF_SingleFaceInfo singleFaceInfo)
        {
            if (image.Width > 1536 || image.Height > 1536)
            {
                image = UtilTool.ScaleImage(image, 1536, 1536);
            }
            else
            {
                image = UtilTool.ScaleImage(image, image.Width, image.Height);
            }
            if (image == null)
            {
                singleFaceInfo = new ASF_SingleFaceInfo();
                ASF_FaceFeature emptyFeature  = new ASF_FaceFeature();
                IntPtr          pEmptyFeature = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_FaceFeature>());
                UtilToolMemory.StructureToPtr(emptyFeature, pEmptyFeature);
                return(pEmptyFeature);
            }
            ImageInfo imageInfo = UtilTool.ReadImage(image);

            if (imageInfo == null)
            {
                singleFaceInfo = new ASF_SingleFaceInfo();
                ASF_FaceFeature emptyFeature  = new ASF_FaceFeature();
                IntPtr          pEmptyFeature = UtilToolMemory.Malloc(UtilToolMemory.SizeOf <ASF_FaceFeature>());
                UtilToolMemory.StructureToPtr(emptyFeature, pEmptyFeature);
                return(pEmptyFeature);
            }
            ASF_MultiFaceInfo multiFaceInfo = DetectFace(pEngine, imageInfo);

            singleFaceInfo = new ASF_SingleFaceInfo();
            IntPtr pFaceModel = ExtractFaceFeature(pEngine, imageInfo, multiFaceInfo, out singleFaceInfo);

            UtilToolMemory.Free(imageInfo.imgData);
            return(pFaceModel);
        }
Exemple #2
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();
        }
Exemple #3
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();
            }
        }