C#:汉王人证比对演示程序示例

演示程序界面

源代码
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;
            }
        }
    }
}

Comments are closed.