汉王人脸识别:活体判断SDK调用示例

演示程序界面

源代码:
FaceLivenessWindow.xaml

<Window x:Class="Splash.FaceLivenessWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:controls="clr-namespace:AForge.Controls;assembly=AForge.Controls"
        mc:Ignorable="d"
        Title="汉王人脸仪-人脸活体判断演示示例 By 秦建辉" SizeToContent="WidthAndHeight" Closing="Window_Closing" Loaded="Window_Loaded" Icon="FaceIdentifyDemo.ico" WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Grid Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>

            <Label Grid.Row="0" Grid.Column="0" Margin="4" Content="请选择可见光摄像头:"/>
            <Label Grid.Row="0" Grid.Column="1" Margin="4" Content="请选择红外摄像头:"/>

            <ComboBox Grid.Row="1" Grid.Column="0" Margin="4" Name="comboBoxNature" DisplayMemberPath="Name" IsReadOnly="True" SelectedIndex="-1" SelectionChanged="ComboBoxNature_SelectionChanged"/>
            <ComboBox Grid.Row="1" Grid.Column="1" Margin="4" Name="comboBoxInfra" DisplayMemberPath="Name" IsReadOnly="True" SelectedIndex="-1" SelectionChanged="ComboBoxInfra_SelectionChanged"/>

            <TabControl Grid.Row="2" Grid.Column="0" Margin="4" Name="tabControlNature">
                <TabItem Header="可见光视频" Width="120">
                    <WindowsFormsHost Margin="4" Width="320" Height="240">
                        <controls:VideoSourcePlayer x:Name="vspNature"/>
                    </WindowsFormsHost>
                </TabItem>

                <TabItem Header="可见光图像" Width="120">
                    <Image Name="imageNature" Margin="4" Width="320" Height="240"/>
                </TabItem>
            </TabControl>

            <TabControl Grid.Row="2" Grid.Column="1" Margin="4" Name="tabControlInfra">
                <TabItem Header="红外视频" Width="120">
                    <WindowsFormsHost Margin="4" Width="320" Height="240">
                        <controls:VideoSourcePlayer x:Name="vspInfra"/>
                    </WindowsFormsHost>
                </TabItem>

                <TabItem Header="红外图像" Width="120">
                    <Image Name="imageInfra" Margin="4" Width="320" Height="240"/>
                </TabItem>
            </TabControl>
        </Grid>

        <CheckBox Grid.Row="0" Name="checkBoxShowIrVideo" Content="显示红外图像" VerticalContentAlignment="Center" Margin="4" IsChecked="True" Click="CheckBoxShowIrVideo_Click"/>

        <Button Grid.Row="2" Name="buttonJudge" Content="活体判断" Width="64" Height="32" Margin="4" Click="ButtonJudge_Click"/>

        <GroupBox Grid.Row="3" Header="活体检测结果" Margin="4">
            <TextBlock Name="textBlockAnswer" FontSize="32" MinWidth="120" HorizontalAlignment="Center" Margin="4"/>
        </GroupBox>
    </Grid>
</Window>

FaceLivenessWindow.cs

/* ----------------------------------------------------------
 * 文件名称:FaceLivenessWindow.cs
 * 作者:秦建辉 
 * 
 * 微信:splashcn
 * 
 * 博客:http://www.firstsolver.com/wordpress/
 * 
 * 开发环境: 
 *      Visual Studio V2017 
 *      .NET Framework 4.5.2
 *      AForge.NET Framework 2.2.5
 *      
 * 版本历史:
 *      V1.0    2017年12月01日
 *              汉王人脸仪-人脸活体判断演示示例
------------------------------------------------------------ */
using AForge.Video.DirectShow;
using Com.FirstSolver.FR;
using Com.FirstSolver.Splash;
using System.Threading;
using System.Windows;

namespace Splash
{
    public partial class FaceLivenessWindow : Window
    {
        /// <summary>
        /// 人脸仪双摄像头集合
        /// </summary>
        private readonly CameraPlus[] CameraDevices = new CameraPlus[2] { null, null };

        /// <summary>
        /// 活体检测结论集合
        /// </summary>
        private readonly string[] LivenessConclusion = { "非活体", "活体", "不确定", "检测失败" };

        /// <summary>
        /// 构造函数
        /// </summary>
        public FaceLivenessWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {   // 获取视频设备列表
            FilterInfoCollection VideoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            comboBoxNature.ItemsSource = VideoDevices;
            comboBoxInfra.ItemsSource = VideoDevices;
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            for (int i = 0; i < CameraDevices.Length; i++)
            {
                if (CameraDevices[i] != null)
                {
                    CameraDevices[i].Dispose();
                    CameraDevices[i] = null;
                }
            }
        }

        private void ComboBoxInfra_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if (comboBoxInfra.SelectedIndex == -1) return;

            if (comboBoxInfra.SelectedIndex == comboBoxNature.SelectedIndex)
            {
                MessageBoxPlus.Show(this, "该摄像头已做它用,请重新选择!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (CameraDevices[0] != null) { CameraDevices[0].Dispose(); CameraDevices[0] = null; }

            CameraDevices[0] = new CameraPlus(((FilterInfo)comboBoxInfra.SelectedItem).MonikerString, vspInfra);
            CameraDevices[0].Play();
        }

        private void ComboBoxNature_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if (comboBoxNature.SelectedIndex == -1) return;

            if (comboBoxNature.SelectedIndex == comboBoxInfra.SelectedIndex)
            {
                MessageBoxPlus.Show(this, "该摄像头已做它用,请重新选择!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (CameraDevices[1] != null) { CameraDevices[1].Dispose(); CameraDevices[1] = null; }

            CameraDevices[1] = new CameraPlus(((FilterInfo)comboBoxNature.SelectedItem).MonikerString, vspNature);
            CameraDevices[1].Play();
        }

        private void CheckBoxShowIrVideo_Click(object sender, RoutedEventArgs e)
        {   // 显示或者隐藏红外图像
            tabControlInfra.Visibility = (bool)checkBoxShowIrVideo.IsChecked ? Visibility.Visible : Visibility.Collapsed;
        }

        private void ButtonJudge_Click(object sender, RoutedEventArgs e)
        {
            if (vspInfra.VideoSource == null || !vspInfra.IsRunning)
            {
                MessageBoxPlus.Show(this, "红外摄像头尚未开启!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (vspNature.VideoSource == null || !vspNature.IsRunning)
            {
                MessageBoxPlus.Show(this, "可见光摄像头尚未开启!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            buttonJudge.IsEnabled = false;
            textBlockAnswer.Text = string.Empty;
            tabControlNature.SelectedIndex = 0; // 切换到自然光视频
            tabControlInfra.SelectedIndex = 0;  // 切换到红外视频

            // 启动活体检测线程
            ThreadPool.QueueUserWorkItem(JudgeLivenessHandler);
        }

        private void JudgeLivenessHandler(object state)
        {
            bool GoOn = true;
            for (int i = 0; GoOn; i++)
            {
                using (System.Drawing.Bitmap NaImg = vspNature.GetCurrentVideoFrame()) // 获取自然光图像
                {
                    using (System.Drawing.Bitmap IrImg = vspInfra.GetCurrentVideoFrame()) // 获取红外图像
                    {
                        byte[] IrGrayLinearArray = IrImg.ToGrayLinearArray();
                        byte[] GrayLinearArray = NaImg.ToGrayAndBgraLinearArray(out byte[] BgraLinearArray);

                        LivenessVerdict Verdict = HWFRCore.IsLiveness(IrGrayLinearArray, IrImg.Width, IrImg.Height, BgraLinearArray, GrayLinearArray, NaImg.Width, NaImg.Height);
                        this.Dispatcher.Invoke(() => {
                            textBlockAnswer.Text = i.ToString() + ":" + LivenessConclusion[(int)Verdict];
                            if (Verdict.Equals(LivenessVerdict.YES) || Verdict.Equals(LivenessVerdict.NO))
                            {
                                imageNature.Source = Utils.ToBitmapImage(NaImg);    // 自然光图像
                                imageInfra.Source = Utils.ToBitmapImage(IrImg);     // 红外图像

                                tabControlNature.SelectedIndex = 1; // 切换到自然光图像
                                tabControlInfra.SelectedIndex = 1;  // 切换到红外图像

                                buttonJudge.IsEnabled = true;
                                GoOn = false;
                            }
                        });
                    }
                }
            }
        }
    }
}

CameraPlus.cs

using AForge.Controls;
using AForge.Video.DirectShow;
using System;

namespace Splash
{
    public class CameraPlus : IDisposable
    {
        /// <summary>
        /// 摄像头标识
        /// </summary>
        public readonly string Moniker;

        /// <summary>
        /// 视频播放器
        /// </summary>
        public readonly VideoSourcePlayer Player;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="moniker">摄像头标识</param>       
        /// <param name="player">视频播放器</param>
        public CameraPlus(string moniker, VideoSourcePlayer player)
        {
            Moniker = moniker;
            Player = player;
        }

        /// <summary>
        /// 开启视频
        /// </summary>
        public void Play()
        {
            if (Player.VideoSource == null)
            {
                Player.VideoSource = new VideoCaptureDevice(Moniker);
            }

            if (!Player.IsRunning)
            {
                Player.Start();
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (Player.VideoSource != null && Player.IsRunning)
            {   // 停止视频
                Player.SignalToStop();
                Player.WaitForStop();
            }
        }
    }
}

Comments are closed.