/// <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); } else { //重置显示消息 trackUnit.message = ""; } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { isLock = false; } } isLock = 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; /* *通信部分,将内存中的数据存放到数据库中 */ //将身份证数据传入到服务器上 //sendMessageToServer(); //将比对结果放到显示消息中,用于最新显示 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); }