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