同系列文章
工程下载
软件界面
源代码
FaceDetectMainWindow.xaml.cs
/* ---------------------------------------------------------- * 文件名称:FaceDetectMainWindow.xaml.cs * 作者:秦建辉 * * 微信:splashcn * * 博客:http://www.firstsolver.com/wordpress/ * * 开发环境: * Visual Studio V2017 * .NET Framework 4 * * 版本历史: * V1.0 2018年03月27日 * 人脸检测演示Demo ------------------------------------------------------------ */ using AForge.Video.DirectShow; using Com.FirstSolver.FR; using Com.FirstSolver.Splash; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; namespace Splash { public partial class FaceDetectMainWindow : Window { public FaceDetectMainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { // 设定初始视频设备 ComboBoxVideoDevices.ItemsSource = new FilterInfoCollection(FilterCategory.VideoInputDevice); ComboBoxVideoDevices.DisplayMemberPath = "Name"; if (ComboBoxVideoDevices.Items.Count > 0) { ComboBoxVideoDevices.SelectedIndex = 0; if (ComboBoxVideoDevices.Items.Count == 1) ComboBoxVideoDevices.IsEnabled = false; } else { ButtonPlay.IsEnabled = false; ButtonCapture.IsEnabled = false; } } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (VSP.VideoSource != null && VSP.IsRunning) { // 停止视频 VSP.SignalToStop(); VSP.WaitForStop(); // 改变按钮为“开始”状态 ButtonPlay.Content = "开启视频"; ButtonCapture.IsEnabled = false; } } private void ButtonOpenFile_Click(object sender, RoutedEventArgs e) { try { Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog { Filter = "Image|*.jpg;*.bmp;*.png;*.tif;*.tga;*.ras;*.jp2;*.j2k;*.jpe", DereferenceLinks = true }; this.CenterChild(); if (dlg.ShowDialog(Owner).Value == true) { using (FileStream fs = new FileStream(dlg.FileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { byte[] source = new byte[fs.Length]; fs.Read(source, 0, (int)fs.Length); BitmapImage image = new BitmapImage(); image.BeginInit(); image.StreamSource = new MemoryStream(source); image.EndInit(); ImageOriginal.Source = image; ImageOriginal.Tag = image.ToJpegByteArray(); TabControlSource.SelectedIndex = 1; } // 检测人脸 ButtonFaceDetect.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); } } catch (System.Exception exception) { MessageBoxPlus.Show(this, exception.Message, "图像文件异常", MessageBoxButton.OK, MessageBoxImage.Error); } } private void ButtonPlay_Click(object sender, RoutedEventArgs e) { TabControlSource.SelectedIndex = 0; if (VSP.VideoSource != null && VSP.IsRunning) { // 停止视频 VSP.SignalToStop(); VSP.WaitForStop(); // 改变按钮为“开始”状态 ButtonPlay.Content = "开启视频"; ButtonCapture.IsEnabled = false; } else if (ComboBoxVideoDevices.SelectedIndex != -1) { // 开启视频 VSP.VideoSource = new VideoCaptureDevice(((FilterInfo)ComboBoxVideoDevices.SelectedItem).MonikerString); VSP.Start(); if (VSP.IsRunning) { // 改变按钮为“停止”状态 ButtonPlay.Content = "停止视频"; ButtonCapture.IsEnabled = true; } } } // 抓拍图像 private void ButtonCapture_Click(object sender, RoutedEventArgs e) { using (System.Drawing.Bitmap bmp = VSP.GetCurrentVideoFrame()) { BitmapImage image = bmp.ToBitmapImage(); ImageOriginal.Source = image; ImageOriginal.Tag = image.ToJpegByteArray(); TabControlSource.SelectedIndex = 1; } // 检测人脸 ButtonFaceDetect.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); } // 获取人脸特征点 private BitmapImage GetFeatureMap(byte[] image, out int CriticalPoints, out int FeaturePoints) { CriticalPoints = -1; FeaturePoints = -1; if (image == null) return null; FrCore Core = null; try { switch (ComboBoxAlgorithm.SelectedIndex) { case 0: { // 百度AI Core = new BaiduFr(); break; } case 1: { // 腾讯AI Core = new TencentFr(); break; } case 2: { // 旷视科技 Core = new MegviiFr(); break; } default: { return null; } } LabelCompany.Content = Core.Company; // 显示厂家名称 if (Core.Initialize() == 0 && Core.Detect(image, out FFI[] faceset) == 0) { // 显示人脸框及特征点 using (MemoryStream ms = new MemoryStream(image)) { using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms)) { using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp)) { foreach (FFI face in faceset) { using (System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.Green, 3.0f)) { // 用矩形框标记人脸位置 g.DrawRectangle(pen, face.Region); } // 标记关键点 if (face.CriticalPoints != null) { using (System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Red)) { foreach (var point in face.CriticalPoints) { int x = point.X; int y = point.Y; g.FillEllipse(brush, x - 2, y - 2, 5, 5); } } CriticalPoints = face.CriticalPoints.Length; } // 标记特征点 if (face.FeaturePoints != null) { using (System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(System.Drawing.Color.Yellow)) { foreach (var point in face.FeaturePoints) { int x = point.X; int y = point.Y; g.FillEllipse(brush, x - 1, y - 1, 3, 3); } } FeaturePoints = face.FeaturePoints.Length; } } } return bmp.ToBitmapImage(); } } } else { MessageBoxPlus.Show(this, Core.ErrorMessage, "人脸检测失败", MessageBoxButton.OK, MessageBoxImage.Warning); } } finally { if (Core != null) Core.Close(); } return null; } // 保存图像 private void ButtonSaveImage(object sender, RoutedEventArgs e) { try { int Tag = System.Convert.ToInt32(((Button)sender).Tag); BitmapImage bmp; if (Tag == 0) { // 保存原始图像 bmp = ImageOriginal.Source as BitmapImage; } else { // 保存人脸特征图像 bmp = ImageFaceFeature.Source as BitmapImage; } if (bmp != null) { Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog { Filter = "Image|*.jpg", DefaultExt = ".jpg" }; if (dlg.ShowDialog() == true) { var encoder = new JpegBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bmp)); using (FileStream stream = new FileStream(dlg.FileName, FileMode.Create)) { encoder.Save(stream); } MessageBoxPlus.Show(this, "保存图像成功", "成功", MessageBoxButton.OK, MessageBoxImage.Information); } } } catch (System.Exception exception) { MessageBoxPlus.Show(this, exception.Message, "保存图像失败", MessageBoxButton.OK, MessageBoxImage.Error); } } // 检测人脸 private void ButtonFaceDetect_Click(object sender, RoutedEventArgs e) { ButtonFaceDetect.IsEnabled = false; ImageFaceFeature.Source = GetFeatureMap(ImageOriginal.Tag as byte[], out int CriticalPoints, out int FeaturePoints); TextBoxCriticalPoints.Text = CriticalPoints.ToString(); TextBoxFeaturePoints.Text = FeaturePoints.ToString(); ButtonFaceDetect.IsEnabled = true; } } }
FaceDetectMainWindow.xaml
<Window x:Class="Splash.FaceDetectMainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:AForge.Controls;assembly=AForge.Controls" Title="人脸检测" FontSize="16" SizeToContent="WidthAndHeight" Icon="FR.ico" ResizeMode="CanMinimize" WindowStartupLocation="CenterScreen" Loaded="Window_Loaded" Closing="Window_Closing"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Orientation="Horizontal"> <Label Margin="4" Content="算法选择"/> <ComboBox Margin="4" MinWidth="160" MaxWidth="320" Name="ComboBoxAlgorithm" SelectedIndex="0"> <ComboBoxItem Content="百度AI"/> <ComboBoxItem Content="腾讯AI"/> <ComboBoxItem Content="旷视科技"/> </ComboBox> <Button Margin="4" Padding="8,0" Content="选择图像文件…" Name="ButtonOpenFile" Click="ButtonOpenFile_Click"/> </StackPanel> <Grid Grid.Row="1" Margin="4"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TabControl Grid.Column="0" Margin="4" Name="TabControlSource"> <TabItem Header="视频" MinWidth="80"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <WindowsFormsHost Grid.Row="0" Margin="4" Width="640" Height="480"> <controls:VideoSourcePlayer x:Name="VSP"/> </WindowsFormsHost> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <ComboBox Grid.Column="0" Margin="4" Name="ComboBoxVideoDevices"/> <Button Grid.Column="1" Margin="4" Padding="8,0" Name="ButtonPlay" Content="开启视频" Click="ButtonPlay_Click"/> <Button Grid.Column="2" Margin="4" Padding="8,0" IsEnabled="False" Name="ButtonCapture" Content="抓拍图像" Click="ButtonCapture_Click"/> </Grid> </Grid> </TabItem> <TabItem Header="图像" MinWidth="80"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <Border Grid.Row="0" Margin="4" BorderBrush="Green" BorderThickness="1"> <Image Width="640" Height="480" Name="ImageOriginal"/> </Border> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Button Grid.Column="0" Margin="4" Padding="8,0" Content="检测人脸" Name="ButtonFaceDetect" Click="ButtonFaceDetect_Click"/> <Button Grid.Column="2" Margin="4" Padding="8,0" Tag="0" Content="保存图像" Click="ButtonSaveImage"/> </Grid> </Grid> </TabItem> </TabControl> <Grid Grid.Column="1"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Label Grid.Row="0" Margin="4,4,4,0" Background="LightGray" HorizontalContentAlignment="Center" Content="人脸特征点" Name="LabelCompany"/> <Border Grid.Row="1" Margin="4" BorderBrush="Green" BorderThickness="1"> <Image Width="640" Height="480" Name="ImageFaceFeature"/> </Border> <Grid Grid.Row="2"> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <StackPanel Grid.Column="0" Orientation="Horizontal"> <Label Margin="4" Content="关键点个数"/> <TextBox Margin="4" MinWidth="120" Background="LightGray" IsReadOnly="True" VerticalContentAlignment="Center" Name="TextBoxCriticalPoints"/> <Label Margin="4" Content="特征点个数"/> <TextBox Margin="4" MinWidth="120" Background="LightGray" IsReadOnly="True" VerticalContentAlignment="Center" Name="TextBoxFeaturePoints"/> </StackPanel> <Button Grid.Column="1" Margin="4" Padding="8,0" Tag="1" Content="保存图像" Click="ButtonSaveImage"/> </Grid> </Grid> </Grid> </Grid> </Window>