源代码
FaceIdentifyForm.cs
/* ---------------------------------------------------------- * 文件名称:FaceIdentifyForm.cs * 作者:秦建辉 * * 微信:splashcn * * 博客:http://www.firstsolver.com/wordpress/ * * 开发环境: * Visual Studio V2017 * .NET Framework 4.5.2 * AForge.NET Framework 2.2.5 * * 版本历史: * V1.0 2017年09月13日 * 人证比对演示程序 ------------------------------------------------------------ */ using AForge.Video.DirectShow; using Com.FirstSolver.FR; using Com.FirstSolver.CardReader; using Com.FirstSolver.Splash; using System; using System.Drawing; using System.IO; using System.Threading; using System.Windows.Forms; namespace Splash { public partial class FaceIdentifyForm : Form { /// <summary> /// 人脸框画笔 /// </summary> private Pen FaceReaderPen = new Pen(Color.Red, 5.0f); /// <summary> /// 身份证读卡器 /// </summary> private IDCardReader CardReader = null; /// <summary> /// 身份证读卡器同步事件 /// </summary> private ManualResetEvent CardReaderSyncEvent = new ManualResetEvent(true); /// <summary> /// 人脸识别核心 /// </summary> private HWFRCore FaceReader = null; /// <summary> /// 是否正在比对人脸 /// </summary> private volatile bool IsCapturing = false; /// <summary> /// 参考图像人脸特征 /// </summary> private byte[] ReferenceFeature; /// <summary> /// 人证比对通过阈值 /// </summary> private float Threshold = 0.7f; public FaceIdentifyForm() { InitializeComponent(); } private void FaceIdentifyForm_Load(object sender, EventArgs e) { // 设置身份证刷卡提示 pictureBoxPhoto.BackgroundImage = Properties.Resources.CardTips; // 初始化摄像头 InitializeCamera(); // 初始化读卡设备 InitializeCardReader(); // 初始化人证比对引擎 InitializeFaceReader(); } // 摄像头选择改变事件处理 private void comboBoxVideoDevices_SelectedIndexChanged(object sender, EventArgs e) { CloseCamera(); if (comboBoxVideoDevices.SelectedIndex != -1) { // 开启视频 vsp.VideoSource = new VideoCaptureDevice(((FilterInfo)comboBoxVideoDevices.SelectedItem).MonikerString); vsp.Start(); } } private void FaceIdentifyForm_FormClosing(object sender, FormClosingEventArgs e) { CloseCamera(); // 关闭摄像头 CloseCardReader(); // 关闭读卡设备 CloseFaceReader(); // 关闭人证比对引擎 FaceReaderPen.Dispose(); } private void buttonResetCamera_Click(object sender, EventArgs e) { InitializeCamera(); } // 初始化摄像头 private void InitializeCamera() { CloseCamera(); // 关闭摄像头 // 设定初始视频设备 comboBoxVideoDevices.DataSource = new FilterInfoCollection(FilterCategory.VideoInputDevice); comboBoxVideoDevices.DisplayMember = "Name"; if (comboBoxVideoDevices.Items.Count > 0) { comboBoxVideoDevices.SelectedIndex = 0; if (comboBoxVideoDevices.Items.Count == 1) comboBoxVideoDevices.Enabled = false; } else { MessageBoxPlus.Show(this, "未发现摄像头!", "摄像头错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // 关闭摄像头 private void CloseCamera() { if (vsp.VideoSource != null && vsp.IsRunning) { // 停止视频 vsp.SignalToStop(); vsp.WaitForStop(); } } private void buttonResetCardReader_Click(object sender, EventArgs e) { InitializeCardReader(); } // 初始化读卡器 private void InitializeCardReader() { CloseCardReader(); // 关闭读卡器 try { CardReader = new YAReader(); CardReader.ExternalSyncEvent = CardReaderSyncEvent; // 身份证读卡器同步信号 CardReader.OnReadCardCompleted += ReadCardCompletedHandler; // 事件处理器 if (CardReader.Start(IDCardBiometrics.Photo) == -1) { MessageBoxPlus.Show(this, "开启身份证扫描服务失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } catch (Exception exception) { MessageBoxPlus.Show(this, exception.Message, "读卡器错误", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } // 停止身份证扫描服务 private void CloseCardReader() { if (CardReader != null) { CardReader.Close(); CardReader = null; } } // 刷身份证处理器 private void ReadCardCompletedHandler(object sender, ReadCardCompletedEventArgs e) { if (e == null || e.Photo == null) return; Image ExpiredBackgroundImage = pictureBoxPhoto.BackgroundImage; using (MemoryStream ms = new MemoryStream(e.Photo)) { pictureBoxPhoto.BackgroundImage = new Bitmap(ms); } if (ExpiredBackgroundImage != null) ExpiredBackgroundImage.Dispose(); } // 选择比对照片 private void buttonSelectPhoto_Click(object sender, EventArgs e) { OpenFileDialog openDialog = new OpenFileDialog(); openDialog.Filter = "Image|*.bmp;*.jpg;*.jpe;*.png"; openDialog.DereferenceLinks = true; if (openDialog.ShowDialog(this) == DialogResult.OK) { Image ExpiredBackgroundImage = pictureBoxPhoto.BackgroundImage; pictureBoxPhoto.BackgroundImage = new Bitmap(openDialog.FileName, true); if (ExpiredBackgroundImage != null) ExpiredBackgroundImage.Dispose(); } } // 初始化人证比对引擎 private void InitializeFaceReader() { try { FaceReader = new HWFRCore(); } catch { MessageBoxPlus.Show(this, "人证比对核心加载失败!,程序退出…", "核心加载错误", MessageBoxButtons.OK, MessageBoxIcon.Error); this.Close(); } } // 关闭人证比对引擎 private void CloseFaceReader() { if (FaceReader != null) FaceReader.Dispose(); } // 参考图像更换事件处理 private void pictureBoxPhoto_BackgroundImageChanged(object sender, EventArgs e) { pictureBoxAnswer.BackgroundImage = Properties.Resources.noimage; textBoxScore.Clear(); if (vsp.VideoSource == null || pictureBoxPhoto.BackgroundImage == null) return; Bitmap bmp = (Bitmap)pictureBoxPhoto.BackgroundImage; byte[] RgbLinearArray; byte[] GrayLinearArray = bmp.ToGrayLinearArray(out RgbLinearArray); // 检测人脸 bool IsOK = false; FR_TFACEINFO FaceInfo; if (FaceReader.DetectOne(GrayLinearArray, RgbLinearArray, bmp.Width, bmp.Height, out FaceInfo) == 1) { // 绘制人脸框 using (Graphics g = Graphics.FromImage(bmp)) { // 用矩形框标记脸位置 FR_TRECT Face = FaceInfo.m_FaceRect; g.DrawRectangle(FaceReaderPen, Face.left, Face.top, Face.right - Face.left + 1, Face.bottom - Face.top + 1); } pictureBoxPhoto.Invalidate(); ReferenceFeature = FaceReader.ExtractFeature(GrayLinearArray, bmp.Width, bmp.Height, ref FaceInfo); if (ReferenceFeature != null) IsOK = true; } if (IsOK) { IsCapturing = true; } else { MessageBoxPlus.Show(this, "参考图像检测不到人脸,请重新选择!", "检测人脸失败", MessageBoxButtons.OK, MessageBoxIcon.Error); CardReaderSyncEvent.Set(); } } // 阈值更新事件处理 private void textBoxThreshold_TextChanged(object sender, EventArgs e) { if (!float.TryParse(textBoxThreshold.Text, out Threshold)) { MessageBoxPlus.Show(this, "阈值范围为0~1.0!", "阈值设置失败", MessageBoxButtons.OK, MessageBoxIcon.Error); textBoxThreshold.Focus(); } } private void vsp_NewFrame(object sender, ref Bitmap image) { if (!IsCapturing) return; // 检测人脸 byte[] RgbLinearArray; byte[] GrayLinearArray = image.ToGrayLinearArray(out RgbLinearArray); FR_TFACEINFO FaceInfo; if (FaceReader.DetectOne(GrayLinearArray, RgbLinearArray, image.Width, image.Height, out FaceInfo) != 1) return; // 绘制人脸框 using (Graphics g = Graphics.FromImage(image)) { // 用矩形框标记脸位置 FR_TRECT Face = FaceInfo.m_FaceRect; g.DrawRectangle(FaceReaderPen, Face.left, Face.top, Face.right - Face.left + 1, Face.bottom - Face.top + 1); } // 提取人脸特征 byte[] SourceFeature = FaceReader.ExtractFeature(GrayLinearArray, image.Width, image.Height, ref FaceInfo); if (SourceFeature == null) return; // 人证比对 float fScore; if (FaceReader.Compare(SourceFeature, ReferenceFeature, out fScore)) { this.BeginInvoke(new Action(() => { if (fScore >= Threshold) { pictureBoxAnswer.BackgroundImage = Properties.Resources.Ok; } else { pictureBoxAnswer.BackgroundImage = Properties.Resources.No; } textBoxScore.Text = fScore.ToString(); })); // 等待下一次事件触发 CardReaderSyncEvent.Set(); IsCapturing = false; } } } }