人脸检测哪家强?百度、腾讯、旷视大比拼(5)测试工具源码

同系列文章

工程下载

FaceDetect.zip

软件界面

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

Comments are closed.