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