public List <FaceInfo> ScanFaces(Bitmap bitmap)
        {
            List <FaceInfo> singleFaces = new List <FaceInfo>();

            if (bitmap == null)
            {
                return(null);
            }

            //从视频帧中获取 多个人脸的矩形框位置
            ASF_MultiFaceInfo multiFaceInfo = FaceUtil.DetectFace(pImageEngine, bitmap);

            //如果识别出人脸,且当前只有一个人脸
            if (multiFaceInfo.faceNum == 1)
            {
                //将MultiFaceInfo结构体中的数据提取成单人脸数据并放入结构体中
                for (int i = 0; i < multiFaceInfo.faceNum; i++)
                {
                    FaceInfo faceInfo = new FaceInfo();

                    faceInfo.singleFaceInfo.faceRect   = MemoryUtil.PtrToStructure <MRECT>(multiFaceInfo.faceRects + MemoryUtil.SizeOf <MRECT>() * i);
                    faceInfo.singleFaceInfo.faceOrient = MemoryUtil.PtrToStructure <int>(multiFaceInfo.faceOrients + MemoryUtil.SizeOf <int>() * i);

                    singleFaces.Add(faceInfo);
                }
            }
            else
            {
                LoggerService.logger.Info($"当前图片中含有多个人脸或没有人脸,请重新选择单人图片,进行特征提取");
                if (bitmap != null)
                {
                    bitmap.Dispose();
                    Console.WriteLine("释放成功");
                }
            }


            return(singleFaces);
        }
Exemple #2
0
        //对每一帧的图片进行了处理,将该帧画面里检测到所有的人脸进行处理,然后进行显示
        public void DetalDisplay(Image <Bgr, byte> nowFrame)
        {
            //如果有有效的bgr位图像则进行人工智能工作和picturView的显示
            if (nowFrame != null)
            {
                using (Bitmap nowFrameBitmap = nowFrame.ToBitmap())
                {
                    //将每帧图片中的人脸信息位置获取出来给faceInfos集合,视频模式会多一个faceId来唯一标识人脸
                    List <FaceInfo> faceInfos = faceVideoRecognizer.ScanFaces(nowFrameBitmap);

                    if (isRGBLock == false)
                    {
                        isRGBLock = true;

                        for (int i = 0; i < faceInfos.Count; i++)
                        {
                            //faceInfo 是相机所检测到的人脸信息(带feceId)都会缓存在这个列表中,faceId不变的话,faceInfo可以找到,就把当前的脸的位置替换了,
                            //但如果faceId变化了,就把新检测到的这张脸添加进列表
                            int findindex = faceInfo.FindIndex(temp => temp.faceId == faceInfos[i].faceId);
                            //如果当前摄像设备之前没有侦测过任何人脸,或者在设备人脸缓存中未找到匹配的Faceid
                            if (faceInfo.Count == 0 || findindex < 0)
                            {
                                FaceInfo tempFaceInfo = new FaceInfo();
                                faceInfos[i].getCopy(tempFaceInfo);
                                tempFaceInfo.frameNum++;
                                tempFaceInfo.dateTime = DateTime.Now.ToLocalTime();
                                faceInfo.Add(tempFaceInfo);
                            }
                            //如果在人脸缓存中有该faceid的对象
                            else
                            {
                                faceInfos[i].getCopy(faceInfo[findindex]);
                                faceInfo[findindex].frameNum++;
                                faceInfo[findindex].dateTime = DateTime.Now.ToLocalTime();
                                if (faceInfo[findindex].isFacePass == true)
                                {
                                    faceInfos[i].studentId = faceInfo[findindex].studentId;
                                }
                                else
                                {
                                    //如果没有比对成功,frameNum超过十次,等400ms再次提取特征值再比对,抽帧
                                    if (faceInfo[findindex].frameNum % 10 == 0)
                                    {
                                        faceInfo[findindex].isGetFeature = false;
                                        if (faceInfo[findindex].faceFeature.feature != IntPtr.Zero)
                                        {
                                            faceInfo[findindex].freeFeature();
                                        }
                                    }
                                }
                            }
                        }

                        for (int i = 0; i < faceInfo.Count; i++)
                        {
                            if ((DateTime.Now - faceInfo[i].dateTime).TotalSeconds > 5)//如果当前人脸未出现在视频中5秒则清除该人脸缓存信息
                            {
                                faceInfo[i].Dispose();
                                faceInfo.RemoveAt(i);
                                i--;
                                continue;
                            }

                            //camera缓冲里的照片进行遍历,没有提取过特征或者没有比对成功过
                            if (faceInfo[i].isGetFeature == false || faceInfo[i].isFacePass == false)
                            {
                                FaceInfo tempFaceInfo = faceInfo[i];

                                //提取特征值
                                faceVideoRecognizer.ScanFaceFeature(nowFrameBitmap, tempFaceInfo);
                                tempFaceInfo.isGetFeature = true;

                                //创建一个线程放进这个线程池(资源系统自己维护),因为人脸对比消耗时间较多
                                //所以将每次需要人脸比对的操作都放进一个线程中
                                ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
                                {
                                    if (tempFaceInfo.isGetFeature == true)
                                    {
                                        tempFaceInfo.isFacePass = compareFeature(tempFaceInfo);
                                        //通过Http post方式 发送json数据
                                        if (tempFaceInfo.isFacePass == true)
                                        {
                                            sendCheckIn(tempFaceInfo);
                                        }
                                    }
                                }));
                            }
                        }

                        for (int i = 0; i < faceInfos.Count; i++)
                        {
                            int x      = faceInfos[i].singleFaceInfo.faceRect.left;
                            int width  = faceInfos[i].singleFaceInfo.faceRect.right - x;
                            int y      = faceInfos[i].singleFaceInfo.faceRect.top;
                            int height = faceInfos[i].singleFaceInfo.faceRect.bottom - y;


                            Rectangle rect = new Rectangle(x, y, width, height);

                            CvInvoke.Rectangle(nowFrame, rect, new MCvScalar(0, 0, 255), 3);
                            CvInvoke.PutText(nowFrame, $"FaceId: {faceInfos[i].faceId}, StudentId: {faceInfos[i].studentId}", new Point(x, y - 15), Emgu.CV.CvEnum.FontFace.HersheySimplex, 1, new MCvScalar(0, 0, 255), 3);
                        }

                        for (int i = 0; i < faceInfos.Count; i++)
                        {
                            faceInfos[i].Dispose();
                            faceInfos[i] = null;
                        }

                        faceInfos.Clear();
                        isRGBLock = false;
                    }
                }

                //显示到屏幕中
                if (PictrueBoxId != null)
                {
                    PictrueBoxId.Invoke(new Action(() =>
                    {
                        if (PictrueBoxId != null)
                        {
                            PictrueBoxId.Image = nowFrame;
                        }
                        PictrueBoxId.Refresh();
                    }));
                }
            }
        }